SQL 不同隔离级别分别解决什么问题?

12次阅读

sql隔离级别按严格性分为读未提交、读已提交、可重复读、串行化四级,分别解决脏读、不可重复读、幻读及写偏斜问题,性能与安全性逐级权衡。

SQL 不同隔离级别分别解决什么问题?

SQL 的隔离级别主要解决多个事务并发执行时产生的数据一致性问题。不同级别在性能和安全性之间做权衡,核心是控制一个事务能看到其他事务的哪些修改。

读未提交(Read Uncommitted)

最低隔离级别,允许一个事务读取另一个事务尚未提交的数据,即“脏读”。它不解决任何并发问题,只避免了写写冲突(如两个事务同时更新同一行时的锁等待),但可能读到回滚掉的数据。

  • 典型场景:极少用于生产,仅在对数据准确性无要求、追求极致读性能的统计分析中临时使用
  • 注意:即使没显式开启事务,某些数据库(如 SQL Server)在 autocommit 关闭时也可能进入该模式

读已提交(Read Committed)

解决脏读问题,确保只能读到已提交的数据。大多数数据库(如 postgresql、SQL Server、oracle)默认采用此级别。

  • 仍可能发生不可重复读:同一事务内多次读取同一行,结果可能不同(因其他事务中途提交了修改)
  • 也可能发生幻读:同一事务内两次执行相同范围查询,返回的行数不同(因其他事务插入或删除了符合 WHERE 条件的行)
  • 实现通常依赖行级快照或语句级锁,每次 select 都看到最新的已提交版本

可重复读(Repeatable Read)

解决脏读和不可重复读,保证事务内多次读取同一行的结果一致。mysql InnoDB 默认使用此级别,并通过间隙锁(Gap Lock)进一步缓解幻读。

  • 在 MySQL 中基本能阻止幻读(对当前读,如 SELECT … for UPDATE),但快照读(普通 SELECT)仍可能看到幻行,取决于 MVCC 实现
  • PostgreSQL 的可重复读基于快照隔离(SI),不会出现幻读,但可能遇到序列化异常(如 A/B 事务各自检查再插入,导致违反唯一约束)
  • 可能出现写偏斜(Write Skew):两个事务读取不同但相关的数据,各自做出修改后提交,破坏业务逻辑约束

串行化(Serializable)

最高隔离级别,完全避免脏读、不可重复读、幻读,以及写偏斜等所有并发异常。它让并发事务的效果等价于按某种顺序串行执行。

  • 实现方式包括严格的两阶段锁(2PL)、可串行化快照隔离(SSI)等
  • 代价是显著降低并发度,容易引发锁等待甚至死锁,吞吐量下降明显
  • 适合强一致性场景,如金融核心账务、库存扣减等不能容忍任何逻辑冲突的操作

选择隔离级别要结合业务容忍度、性能需求与数据库实际行为。不要盲目追求高隔离,也不应忽视低级别带来的隐性风险。

text=ZqhQzanResources