我的意思是像成千上万的用户及时更新数据库中的值?
4 回答
是的,nextval
从多个并发操作的事务中使用是安全的。这就是它的目的和存在的理由。
也就是说,它实际上并不是“线程安全的”,因为 PostgreSQL 使用多处理模型而不是多线程模型,并且因为大多数客户端驱动程序(例如 libpq)一次不允许超过一个线程与单个连接进行交互。
您还应该知道,虽然nextval
可以保证返回不同且不断增加的值,但不能保证在没有“洞”或“间隙”的情况下这样做。当生成的值被丢弃而不被提交(例如,由 a 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 无间隙序列”以获取更多信息。
是:http ://www.postgresql.org/docs/current/static/functions-sequence.html
否则它不会有用。
编辑:这是你如何使用 nextval 和 currval:
nextval 返回一个新的序列号,您可以将其用于第一个表的插入中的 id
currval 返回此会话获得的最后一个序列号,您在外键中使用它来引用第一个表
每次调用 nextval 都会返回另一个值,不要在同一组插入中调用它两次。
当然,您应该在任何多用户代码中使用事务。
这张海报对同一个有缺陷的代码提出了不同的问题。 这里的重点是:他似乎不知道外键是如何工作的,并且将它们颠倒过来(作为外键的序列有点尴尬恕我直言)
顺便说一句:这应该是评论,而不是答案;但我还不能发表评论。