Postgres并发插入场景下ID分配与数据可见性问题咨询
PostgreSQL插入并行场景的问题解答
背景信息
表结构定义:
create table mytable(id SERIAL, largeImage bytea);
场景:进程A先到达数据库服务但携带超大文件,进程B后到达但文件很小,二者同时执行插入操作。假设插入并行执行,SERIAL类型的ID通过nextval()分配,且B的磁盘写入速度快于A。
问题1:进程A会被分配ID=1,进程B被分配ID=2,该结论是否正确?
结论:不一定正确。
SERIAL类型的ID依赖序列的nextval()函数生成,而nextval()的调用时机是插入语句执行到分配ID的环节,不是请求到达数据库服务的时间点。如果进程A因大文件传输延迟,导致它的插入语句中nextval()的调用晚于进程B,那么B会拿到ID=1,A拿到ID=2。只有当A的nextval()调用确实早于B时,才会是A=1、B=2。
问题2:是否存在(概率较低但可能)select * from mytable仅返回ID=2的情况,原因是进程A的磁盘写入操作尚未完成?
结论:存在这种可能。
PostgreSQL默认使用**读已提交(READ COMMITTED)**隔离级别。如果进程A的插入事务因为大文件写入耗时久,还未提交;而进程B的插入事务已经完成提交,此时执行查询只能看到已提交的B的记录(ID=2)。只有当A的事务提交后,它的记录才会被其他事务查询到。
内容的提问来源于stack exchange,提问作者danipenaperez
相关产品推荐
相关产品推荐

