SQL事务隔离依赖锁机制、MVCC和可见性规则协同实现,核心在于厘清读写主体、时机及数据版本判定;隔离级别仅定义可见性规则,不直接控制锁。

SQL事务隔离不是靠“设个级别就完事”,而是数据库在并发读写时,通过锁机制、多版本控制(MVCC)和可见性规则共同作用的结果。理解它,关键要拆清“谁在读、谁在写、什么时候读、数据版本怎么判定”这四条线。
隔离级别决定“可见性规则”,不直接控制锁
很多人以为设置 READ COMMITTED 就等于“不加锁”,其实不然——它只规定“只能看到已提交的数据”,但实现方式因引擎而异:
- InnoDB 默认用 MVCC:普通 SELECT 不加锁,靠 Read View 判断某行对当前事务是否可见;UPDATE/DELETE 仍会对目标行加行锁
- SQL Server 在 READ COMMITTED 下默认使用共享锁(锁读),读完即放,所以可能遇到不可重复读
- PostgreSQL 全面依赖 MVCC,连锁读都避免,靠快照隔离(SI)实现
真正影响性能瓶颈的,往往不是隔离级别本身,而是它背后触发的锁范围和持有时间。
脏读、不可重复读、幻读,本质是“读到了不该读的版本”
这三类现象不是孤立 bug,而是同一逻辑链条上的不同断裂点:
- 脏读:读到了其他事务未提交的中间态版本(比如事务A改了name但没提交,事务B读到了)→ 源于 Read View 生成太早或未校验提交状态
- 不可重复读:同一事务中两次读同一行,结果不同(比如事务A第一次读 age=25,事务B提交更新为26,A再读变成26)→ Read View 复用失败,第二次读用了新快照
- 幻读:同一事务中两次执行相同范围查询,返回行数不同(比如事务A查 status=0 的订单有3条,事务B插入1条并提交,A再查变4条)→ 范围条件未被锁住,或新插入行的版本在当前 Read View 中“意外可见”
注意:幻读在 InnoDB 的可重复读(RR)下仍可能发生(如 insert 新记录),只是通过间隙锁(Gap Lock)+ Next-Key Lock 抑制了“索引区间内”的幻读,不是彻底消除。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~