PostgreSQL游标在READ COMMITTED隔离级别下是否会出现不可重复读或幻读?
PostgreSQL游标在READ COMMITTED隔离级别下的分页一致性问题
传统LIMIT/OFFSET分页的一致性缺陷
在READ COMMITTED隔离级别下,使用LIMIT/OFFSET对大数据集分页时,极易出现数据重复或遗漏的问题。例如执行以下SQL:
-- 隔离级别为 READ COMMITTED SELECT * FROM users ORDER BY age ASC LIMIT :pageSize OFFSET :page * :pageSize
若两次分页请求间隙存在并发事务修改数据(如插入、删除或更新影响排序字段的记录),会导致后续分页出现数据重复展示或部分记录被跳过的情况,本质是触发了幻读或不可重复读。
PostgreSQL游标的表现
PostgreSQL的游标在READ COMMITTED隔离级别下不会出现上述问题,核心原因是游标绑定了事务启动时的数据快照:
- 在事务内声明并打开游标后,游标会基于当前事务的快照读取数据,后续的
FETCH操作只会看到事务启动时的数据状态 - 并发事务对数据的修改(插入、删除、更新)不会被当前游标的
FETCH操作感知,因此不会出现数据重复或遗漏 - 只有关闭游标重新打开,或在新事务中使用游标时,才会基于新的快照读取最新数据
需要注意两个关键点:
- 游标必须在持续的事务中使用,如果每次
FETCH都开启新事务,会回到和LIMIT/OFFSET分页相同的一致性问题 - 若事务结束前关闭游标,再次打开会重新获取当前的最新数据快照
内容的提问来源于stack exchange,提问作者Tiddo
相关产品推荐
相关产品推荐

