🔵网盘资料下载:数据库事务隔离级别详解 提取码: 9b3g
数据库脏读、不可重复读、幻读:面试高频考点解析

在数据库事务隔离级别的面试中,脏读、不可重复读、幻读是必考的三兄弟。它们直接关系到事务的并发控制与数据一致性,也是区分不同隔离级别的核心指标。本文从实际面试场景出发,帮你彻底理清它们的本质差异和解决方案。
一、脏读(Dirty Read):读到未提交的数据
典型场景:事务A修改数据但未提交,事务B读取到修改后的值。
问题根源:事务隔离级别为READ UNCOMMITTED时,允许读取其他事务未提交的数据。
案例:
- 用户转账时,事务A扣除余额但未提交(可能因异常回滚)
- 事务B读取到扣除后的余额,展示给用户
后果:如果事务A回滚,事务B得到的就是错误的"脏数据"。
二、不可重复读(Non-Repeatable Read):同事务内数据不一致
典型场景:事务A多次读取同一数据,事务B在中间修改并提交,导致事务A前后结果不一致。
关键特征:针对已提交的数据修改(UPDATE/DELETE)。
案例:
- 事务A第一次读取库存为100
- 事务B下单并提交,库存变为80
- 事务A再次读取库存变为80
本质:同一事务内无法保证多次读取结果一致。
三、幻读(Phantom Read):凭空出现的数据行
典型场景:事务A按条件查询数据,事务B插入符合条件的新数据并提交,导致事务A再次查询时"多出"数据行。
关键特征:针对数据新增(INSERT)。
案例:
- 事务A统计订单数(当前100条)
- 事务B新增5个订单并提交
- 事务A再次统计变为105条
特殊点:即使使用行锁也无法阻止其他事务插入新数据。
四、三者的核心区别
| 问题类型 | 触发操作 | 数据状态 | 锁机制影响 |
|----------------|------------|----------------|----------------|
| 脏读 | 未提交修改 | 临时数据 | 无锁 |
| 不可重复读 | 已提交修改 | 数据值变化 | 行锁可解决 |
| 幻读 | 已提交新增 | 数据行数变化 | 需要间隙锁 |
五、解决方案:事务隔离级别与锁机制
- READ UNCOMMITTED:不解决任何问题
- READ COMMITTED:解决脏读(Oracle默认)
- REPEATABLE READ:解决脏读、不可重复读(MySQL默认)
- SERIALIZABLE:解决所有问题(性能最低)
重点技术:
- MVCC(多版本并发控制):通过版本链实现非锁定读
- Next-Key Locks:解决幻读(行锁+间隙锁)
- 快照读 vs 当前读:SELECT语句是否加锁
六、实际开发中的选择策略
- 金融系统优先选择REPEATABLE READ
- 高并发读场景使用READ COMMITTED
- 报表统计类操作建议显式加锁
如果需要购买面试鸭会员,可以通过面试鸭返利网找到我,返利25元。

七、高频面试问题模板
Q:说说什么叫幻读?和不可重复读有什么区别?
A:
- 定义:幻读是同一事务内多次查询时,由于其他事务插入新数据导致结果集行数变化
- 对比:不可重复读关注的是数据值的修改,幻读关注的是数据行的新增
- 解决方案:提升隔离级别到SERIALIZABLE,或使用间隙锁(Gap Lock)
掌握这三个概念的核心区别,结合具体的隔离级别和锁机制,就能在面试中游刃有余。记得在实际项目中根据业务场景选择合适的隔离级别,平衡数据一致性与系统性能。



