在使用max ID函数调用sequence的setval时,是否应该锁定PostgreSQL表?
我有以下SQL脚本,它设置与ID列的最大值对应的序列值:在使用max ID函数调用sequence的setval时,是否应该锁定PostgreSQL表?,postgresql,transactions,locking,database-sequence,Postgresql,Transactions,Locking,Database Sequence,我有以下SQL脚本,它设置与ID列的最大值对应的序列值: SELECT SETVAL('mytable_id_seq', COALESCE(MAX(id), 1)) FROM mytable; 在这种情况下,我是否应该锁定“mytable”以防止在并行请求中更改ID,例如下面的示例 请求#1请求#2 最大值(id)=5 插入id 6 SETVAL=5 或者setval(max(id))是一个原子操作?您的怀疑是对的,这种方法受竞争条件的影响 但是锁定表不会有帮助,因为它不会阻止并发事务获取新
SELECT SETVAL('mytable_id_seq', COALESCE(MAX(id), 1)) FROM mytable;
在这种情况下,我是否应该锁定“mytable”以防止在并行请求中更改ID,例如下面的示例
请求#1请求#2
最大值(id)=5
插入id 6
SETVAL=5
或者setval(max(id))是一个原子操作?您的怀疑是对的,这种方法受竞争条件的影响 但是锁定表不会有帮助,因为它不会阻止并发事务获取新的序列值。当表被锁定时,该事务将被阻塞,但一旦锁消失,它将使用在表被锁定时获得的序列值继续插入 如果可以锁定序列,这可能是一个解决方案,但不可能锁定序列 我可以想出两种解决办法:
SELECT SETVAL('mytable_id_seq', COALESCE(MAX(id), 1) + 100000) FROM mytable;
这里100000是一个安全的值,它大于操作运行时可能插入的行数