如何在Postgres中原子地更新序列?
背景:我正在使用SQLAlchemy批量插入对象,但exectutemany
无法返回默认值,因此我想将主键序列逐个增加我需要插入的对象数量。
我知道可以这样做:
ALTER SEQUENCE seq INCREMENT BY 1000;
但我不确定在并发环境下这样做是否安全。
如何在Postgres中原子地更新序列?
背景:我正在使用SQLAlchemy批量插入对象,但exectutemany
无法返回默认值,因此我想将主键序列逐个增加我需要插入的对象数量。
我知道可以这样做:
ALTER SEQUENCE seq INCREMENT BY 1000;
但我不确定在并发环境下这样做是否安全。
setval()
结合 nextval()
。select setval('my_sequence', nextval('my_sequence') + 999);
这个操作会将当前值增加1000,而不是将其设置为固定值。
nextval
1000次。SELECT nextval('common_id_seq') FROM generate_series(1, 1000);
generate_series
执行期间调用另一个nextval()
,导致值不完全按顺序?(我猜这是可能的,所以如果您想为1000个项目分配ID,这是最安全的方法) - Kipcommon_id
可能与创建顺序不匹配,这对于依赖此项的容错系统可能会造成问题。把它放在某种锁后面可能是有意义的。 - Rol这样做是安全的,因为ALTER SEQUENCE
会在序列上获取一个ACCESS EXCLUSIVE
锁。
但是存在两个问题:
这将阻塞所有并发使用序列直到您的事务完成
您不知道起始值
您可以通过以下方式解决第二个问题:
BEGIN;
ALTER SEQUENCE seq INCREMENT BY 1000;
SELECT nextval('seq');
COMMIT;
那么你知道这个值和前面的999个值都是属于你的。
但我认为最好的方法是调用nextval
1000次。