我需要仅通过一个查询从序列中获取多个值。在 Stack Overflow 上我发现了以下内容:
https://stackoverflow.com/questions/896274/select-multiple-ids-from-a-postgresql-sequence
解决方案似乎如下:
select nextval('my_sequence') from generate_series(1, N)
当我的应用程序每次满足某些客户端请求时都可以同时启动此查询时,会如何表现呢?
得票最高的答案有一条评论:
请注意,这 3 个数字(nextvals)不保证是连续的。
我不一定关心顺序性,但是否可以保证返回的值至少严格单调递增,即使它们可能与另一个并发查询生成的值交织在一起?
是的,对于这个简单的查询和默认设置,
SEQUENCE
生成的系列保证严格单调递增。SEQUENCE
甚至可以用负增量创建A !并且,如果您ORDER BY
向同一查询添加连接、分组或其他任何可能重新排序行的操作,则可以根据生成的查询计划相应地打乱生成的数字。但事实并非如此,如果并发交易也从同一序列中提取,则总是会存在差距。对于严格连续的数字,请使用其他工具。手册:
如果每个并发访问都在其自己的会话中运行,之后会关闭,则可以使用
CACHE
序列设置。但这主要是为了加快访问速度,可能会导致其他访问模式的序列间隙更大。而且我甚至不确定缓存是否能保证“无间隙”。有关该主题的更多信息:
使用 hack 获取严格连续的数字
LOCK
不适用于序列。但我们可以使用 间接锁定序列对象
ALTER SEQUENCE
。手册:假设有必要的权限(!)我们可以在同一笔交易中做到这一点:
我们实际上并没有改变序列,但它仍然阻止了与之的所有并发交互。因此,您得到的是严格连续的数字。其他相关事务必须等到您的事务完成并释放锁。这暂时违背了序列优化并发写入访问的目的。但您得到了连续的序列。
您通常不会想将权限授予
ALTER SEQUENCE
随机角色。但您可以将此命令包装在特权函数中,并向任何人授予对该函数的访问权限 - 有效地授予对该序列的独占访问权限...相关:另一个异常情况:如果您的交易以 结尾
ROLLBACK
,则序列将重置为其原始状态,包括您nextval()
调用之前的当前数字。在正常操作中,即使对于回滚交易,这种情况也不会发生。如果您继续使用这些数字,您将遇到独特的违规行为......