首页 >文档 > 数据库脏读 不可重复读 幻读

数据库脏读 不可重复读 幻读

数据库事务隔离级别中的脏读、不可重复读和幻读是面试高频考点,也是保证数据一致性的核心问题。脏读指读取未提交的临时数据,不可重复读是同一事务内多次读取数据值不一致,幻读则是查询结果集行数变化。不同隔离级别(READ UNCOMMITTED到SERIALIZABLE)配合MVCC和锁机制可解决这些问题。MySQL默认REPEATABLE READ通过行锁和间隙锁防止幻读,而Oracle采用READ COMMITTED。开发中需根据业务场景选择合适隔离级别,金融系统推荐REPEATABLE READ,高并发读场景可用READ COMMITTED,报表统计建议显式加锁。理解这些概念能帮助开发者设计更健壮的数据库架构。

🔵网盘资料下载:数据库事务隔离级别详解 提取码: 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条
    特殊点:即使使用行锁也无法阻止其他事务插入新数据。

四、三者的核心区别

| 问题类型 | 触发操作 | 数据状态 | 锁机制影响 |
|----------------|------------|----------------|----------------|
| 脏读 | 未提交修改 | 临时数据 | 无锁 |
| 不可重复读 | 已提交修改 | 数据值变化 | 行锁可解决 |
| 幻读 | 已提交新增 | 数据行数变化 | 需要间隙锁 |


五、解决方案:事务隔离级别与锁机制

  1. READ UNCOMMITTED:不解决任何问题
  2. READ COMMITTED:解决脏读(Oracle默认)
  3. REPEATABLE READ:解决脏读、不可重复读(MySQL默认)
  4. SERIALIZABLE:解决所有问题(性能最低)

重点技术

  • MVCC(多版本并发控制):通过版本链实现非锁定读
  • Next-Key Locks:解决幻读(行锁+间隙锁)
  • 快照读 vs 当前读:SELECT语句是否加锁

六、实际开发中的选择策略

  1. 金融系统优先选择REPEATABLE READ
  2. 高并发读场景使用READ COMMITTED
  3. 报表统计类操作建议显式加锁

如果需要购买面试鸭会员,可以通过面试鸭返利网找到我,返利25元。

面试鸭返利网


七、高频面试问题模板

Q:说说什么叫幻读?和不可重复读有什么区别?
A

  1. 定义:幻读是同一事务内多次查询时,由于其他事务插入新数据导致结果集行数变化
  2. 对比:不可重复读关注的是数据值的修改,幻读关注的是数据行的新增
  3. 解决方案:提升隔离级别到SERIALIZABLE,或使用间隙锁(Gap Lock)

掌握这三个概念的核心区别,结合具体的隔离级别和锁机制,就能在面试中游刃有余。记得在实际项目中根据业务场景选择合适的隔离级别,平衡数据一致性与系统性能。

面试鸭返利网

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

🎯 立即加入面试鸭会员 →