You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL的REPEATABLE_READ事务隔离级别是如何实现的?

PostgreSQL 12 REPEATABLE_READ 隔离级别读异常防护实现逻辑

PostgreSQL 12 的 REPEATABLE_READ 隔离级别核心基于多版本并发控制(MVCC)+ 事务快照机制实现三类读异常的防护,具体逻辑如下:

  • 脏读防护
    脏读指读取到其他未提交事务的修改内容。PostgreSQL 所有隔离级别默认都不会出现脏读:写操作仅生成数据的新版本,不会覆盖原有版本;读操作的可见性由事务快照判断,快照中会记录当前所有未提交的事务ID,这些事务生成的所有数据版本对当前事务完全不可见,从根源上杜绝了脏读的可能。
  • 不可重复读防护
    不可重复读指同一事务内两次执行相同的单行查询,中间其他已提交事务修改了对应行数据,导致两次查询结果不一致。REPEATABLE_READ 级别下,整个事务只会在第一次执行读操作时生成一次全局快照,后续所有查询都复用这个快照,快照生成之后才提交的事务的所有修改对当前事务都不可见,因此同一事务内无论多少次读取同一行数据,结果都完全一致。
  • 幻读防护
    幻读指同一事务内两次执行相同的范围查询,中间其他已提交事务新增/删除了符合查询条件的行,导致第二次查询出现额外的行或者缺少行。PostgreSQL 的 REPEATABLE_READ 实现超出了SQL标准的要求,通过两层逻辑杜绝幻读:一方面快照的可见性规则会过滤掉快照生成后才提交的新增、删除行,读操作本身不会看到符合条件的行发生变化;另一方面如果当前事务要修改某个范围的数据,和快照生成后其他事务提交的同范围修改产生冲突时,会直接抛出 could not serialize access due to concurrent update 错误终止事务,避免逻辑层面的幻读问题。

和 READ_COMMITTED 隔离级别的差异:READ_COMMITTED 级别下每执行一条SQL语句都会生成新的快照,所以每次查询都能看到语句执行前刚提交的其他事务的修改,才会出现不可重复读和幻读问题。REPEATABLE_READ 全程复用单个快照的设计虽然规避了这两类异常,但也会带来对应开销:旧版本数据需要保留到所有持有相关快照的事务结束,会占用一定的存储资源,同时事务提交时的并发冲突检查也会带来少量CPU开销。


内容的提问来源于stack exchange,提问作者Martin Thoma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:00:05