294 字
1 分钟
MySQL 事务异常读:脏读、不可重复读与幻读
| 问题 | 现象 | 典型原因 |
|---|---|---|
| 脏读 | 读到尚未提交、随后可能回滚的数据 | 隔离级别过低 |
| 不可重复读 | 同一事务两次读取同一行,内容不同 | 其他事务 UPDATE/DELETE 并提交 |
| 幻读 | 同一范围查询两次,行数不同 | 其他事务 INSERT/DELETE 匹配行 |
不可重复读关注“同一行内容变了”,幻读关注“符合条件的行数变了”。MVCC 快照读可以缓解不可重复读和部分幻读;当前读还需要间隙锁保护范围。
读已提交为什么不能保证可重复读
读已提交隔离级别下,每次 SELECT 都生成新的 ReadView。事务 B 提交修改后,事务 A 的下一次查询会看到新的已提交版本,因此两次结果可能不同。可重复读会复用第一次查询建立的 ReadView。
为什么 MVCC 仍需要间隙锁
MVCC 主要服务普通快照读;SELECT ... FOR UPDATE、UPDATE、DELETE 等当前读必须读取最新版本。为了阻止其他事务在查询范围内插入新记录,需要通过间隙锁锁住范围。
MySQL 事务异常读:脏读、不可重复读与幻读
https://blog.xqcherry.top/posts/interview/mysql/dirty-read-nonrepeatable-read-phantom-read/ 目录