Yihui’s Blog

数据库的脏读、不可重复读和幻读分别是什么?

日期:2026-07-11
难度:中等
标签:#面试 #MySQL #事务 #隔离级别

一句话答案

脏读是读到未提交数据;不可重复读是同一行两次读结果不同;幻读是同一条件范围两次读,符合条件的行集合增减。

原理拆解

现象并发例子解决思路
脏读T1 改金额未提交,T2 已读到,随后 T1 回滚至少 RC
不可重复读T1 两次读 id=1,间隔 T2 提交更新RR 快照读
幻读T1 两次查 age > 18,T2 插入符合条件的新行快照读或范围锁

面试口语版

三者要按“读到了什么”区分:脏读读的是别人最终可能回滚的未提交值;不可重复读关注同一条已经存在的记录被更新或删除;幻读关注的是一个范围的记录数量或集合发生变化,典型是并发插入。InnoDB 的 RR 对普通 SELECT 用同一快照,重复查询不会看到后来提交的行;对 SELECT FOR UPDATE、更新等当前读,会用 next-key lock 防止其他事务在范围内插入。

关键细节

  • “不可重复读只指更新、幻读只指插入”是便于记忆的典型场景,核心是单行值变化和结果集变化的区别。
  • 快照读不等于读取真实最新数据;库存扣减等必须用条件更新或当前读处理。

面试官追问

  1. RR 的普通读和当前读分别如何处理幻读?
  2. 如何写 SQL 防止超卖?
  3. 不可重复读一定是坏事吗?

学习清单

  • 用两个事务、两次读取的时间线讲清三种现象。
Maintained by · YihuiEdit on GitHub

Keep reading

View all posts