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

在数据库事务的并发控制中,脏读不可重复读幻读是三种常见的并发问题。它们与事务的隔离级别密切相关,不同的隔离级别可以避免或允许这些现象的发生。以下是它们的详细解释:


1. 脏读(Dirty Read)

  • 定义:一个事务读取了另一个事务尚未提交的数据。
  • 场景
    • 事务 A 修改了某条数据,但未提交。
    • 事务 B 读取了事务 A 修改后的数据。
    • 如果事务 A 回滚,事务 B 读取的数据就是无效的(即“脏数据”)。
  • 问题:读取到未提交的数据,可能导致数据不一致。
  • 隔离级别
    • 读未提交(Read Uncommitted) 允许脏读。
    • 读已提交(Read Committed) 及以上隔离级别可以避免脏读。

2. 不可重复读(Non-Repeatable Read)

  • 定义:在同一个事务中,多次读取同一数据,结果不一致。
  • 场景
    • 事务 A 读取某条数据。
    • 事务 B 修改了该数据并提交。
    • 事务 A 再次读取该数据时,发现数据已改变。
  • 问题:同一个事务内多次读取的结果不一致,影响事务的可靠性。
  • 隔离级别
    • 读已提交(Read Committed) 允许不可重复读。
    • 可重复读(Repeatable Read) 及以上隔离级别可以避免不可重复读。

3. 幻读(Phantom Read)

  • 定义:在同一个事务中,多次查询同一范围的数据,结果集不一致(新增或删除了记录)。
  • 场景
    • 事务 A 查询某个范围的数据。
    • 事务 B 插入或删除了符合该范围的数据并提交。
    • 事务 A 再次查询时,发现结果集中多了或少了记录(像幻觉一样)。
  • 问题:范围查询的结果集不一致,影响事务的一致性。
  • 隔离级别
    • 可重复读(Repeatable Read) 允许幻读。
    • 串行化(Serializable) 可以避免幻读。

总结对比

现象描述隔离级别允许隔离级别避免
脏读读取到未提交的数据。读未提交(Read Uncommitted)读已提交(Read Committed)及以上
不可重复读同一事务中多次读取同一数据,结果不一致。读已提交(Read Committed)可重复读(Repeatable Read)及以上
幻读同一事务中多次查询同一范围的数据,结果集不一致(新增或删除记录)。可重复读(Repeatable Read)串行化(Serializable)

如何选择隔离级别?

  • 读未提交:性能最高,但数据一致性最差。
  • 读已提交:避免脏读,适合大多数场景。
  • 可重复读:避免脏读和不可重复读,MySQL 默认隔离级别。
  • 串行化:完全避免脏读、不可重复读和幻读,但性能最低。

在实际应用中,需要根据业务需求和数据一致性要求选择合适的隔离级别。

THE END
点赞12 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容