Skip to content

事务与隔离级别

三种并发问题、PG 的隔离级别(默认 RC)、快照读语义、SSI 可串行化。

Updated View as Markdown
For humans

事务与隔离级别

PostgreSQL 支持标准的四种隔离级别,但两个关键点与 MySQL 不同:默认是读已提交(RC)而不是可重复读可重复读下 PG 不防幻读(没有间隙锁),要严格防幻读只能上可串行化。

三种并发问题

问题 现象
脏读 读到其他事务未提交的数据
不可重复读 同一事务内两次读同一行结果不同
幻读 同一事务内两次范围查询行数不同

四种隔离级别

级别 脏读 不可重复读 幻读
读未提交 可能 可能 可能
读已提交(RC,默认) 解决 可能 可能
可重复读(RR) 解决 解决 可能
可串行化 解决 解决 解决

快照语义:PG 的实现方式

PG 的隔离级别差异就是快照的生成时机:

  • RC:每条语句开始生成新快照。事务内两条 SELECT 之间其他事务提交了,第二条能看到新数据
  • RR:事务第一次读时生成快照,整个事务复用。同一事务内读到的数据始终一致
  • 可串行化:RR 的快照加冲突检测

PG 的 RR 不防幻读:因为没有间隙锁,另一个事务在范围内插入新行后,当前事务虽然看不到(快照),但这是靠快照而非锁实现的“伪防幻读”。需要严格防幻读(如金融对账)时,用可串行化级别。

SSI:可串行化快照隔离

PG 的可串行化不是锁串行化,而是乐观冲突检测:事务并发执行,提交时检测读写依赖是否形成环(SIREAD 锁跟踪读集),检测到冲突就回滚其中一个(报错 40001)。

适用场景:真正需要可串行化保证的并发写入(如并发修改同一范围数据),但冲突率高时回滚多,性能差。多数业务 RC 足够。

与 MySQL 的对比

维度 PostgreSQL MySQL
默认级别 读已提交 可重复读
RR 防幻读 不防(无间隙锁) 防(临键锁)
可串行化实现 SSI 乐观冲突检测 全表锁串行化
隔离机制 纯快照 + 版本链 MVCC 快照读 + 锁当前读

面试高频结论:MySQL 的 RR 靠临键锁防幻读,代价是间隙锁冲突和死锁;PG 的 RC 默认更简单,需要强一致时用 SSI,机制不同各有取舍。

面试追问

  1. PG 默认隔离级别? 读已提交,和 MySQL 的默认可重复读不同
  2. PG 的 RR 防幻读吗? 不防。没有间隙锁,幻读只能靠可串行化级别解决
  3. SSI 是什么? 可串行化快照隔离:乐观并发控制,提交时检测读写冲突,冲突回滚(40001)
  4. RC 和 RR 的快照区别? RC 每条语句新快照,RR 事务复用第一个快照
  5. 什么场景用可串行化? 需要严格防幻读的并发写入(金融对账)。冲突率高时回滚多,性能差,多数业务 RC 足够
Navigation

Type to search…

↑↓ navigate↵ selectEsc close