我的意思是,就像成千上万的用户在不同时间内更新数据库中的值?
我的意思是,就像成千上万的用户在不同时间内更新数据库中的值?
是的,nextval
可以安全地用于多个并发操作的事务中。这就是它存在的目的和原因。
尽管如此,它实际上并非 "线程安全",因为 PostgreSQL 使用的是多进程模型而不是多线程模型,而且大多数客户端驱动程序(例如 libpq)不允许一次有多个线程与单个连接进行交互。
您还应该注意,虽然 nextval
保证返回不同且递增的值,但不能保证没有 "空洞" 或 "间隙"。当生成的值被废弃而未提交时(例如通过 ROLLBACK
),以及 PostgreSQL 在服务器崩溃后恢复时,就会创建这样的空洞。
虽然 nextval
总是会返回递增的数字,但这并不意味着您的事务将按照从给定序列获得 ID 的顺序提交。因此,出现以下情况是完全正常的:
Start IDs in table: [1 2 3 4]
1st tx gets ID 5 from nextval()
2nd tx gets ID 6 from nextval()
2nd tx commits: [1 2 3 4 6]
1st tx commits: [1 2 3 4 5 6]
换句话说,空洞可以出现和消失。
这两个异常都是使一个nextval
调用不会阻塞另一个的必要和不可避免的结果。
如果您想要一个没有这种排序和间隔异常的序列,您需要使用无间隙序列设计,它只允许一个事务同时拥有一个未提交的生成ID,从而有效地消除该表中插入操作的所有并发性。这通常使用在计数器表上的SELECT FOR UPDATE
或UPDATE ... RETURNING
实现。
搜索“PostgreSQL无间隙序列”以获得更多信息。
nextval()
可以从任意数量的事务中调用。 - user330315是的: http://www.postgresql.org/docs/current/static/functions-sequence.html
否则它就没有用处了。
编辑: 以下是nextval和currval的使用方法:
nextval返回一个新的序列号,您可以在第一张表的插入中使用它作为id
currval返回此会话获取的最后一个序列号,您可以在外键中使用它来引用第一张表
每次调用nextval都会返回另一个值,在相同的插入集中不要调用两次。
当然,在任何多用户代码中都应该使用事务。
nextval
在单个事务中重复返回相同的ID吗?它并不会这样做。当你更新你的问题时,请包括你的PostgreSQL版本、所有代码以及完整的错误信息文本。 - Craig Ringer