HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
  • 《LearnJavaToFindAJob》

    • 导读

    • 【初级】6~12k档

    • 【中级】12k-26k档

      • JVM进阶

      • Java进阶

      • MySQL

        • Innodb和MyISAM索引的区别
        • MySQL一些索引失效的场景和原理
        • MySQL如何行转列?
        • MySQL的架构和执行流程
        • MySQL的自增ID用完了会怎样?
        • MySQL索引的分类、何时使用、何时不使用、何时失效?
        • MySQL联合索引在B+数的存储结构和最左匹配原则原理
        • Mysql的索引和主键的区别
        • binlog、redolog、undolog的区别和作用
        • 什么是前缀索引,什么情况才使用?
        • 可重复读是否能解决幻读?
        • 我以为我对Mysql事务很熟,直到我遇到了阿里面试官
        • 聊聊MySQL索引的分类和结构吧
      • 中间件

      • 算法

      • 高阶

    • 【高级】26k+档

    • 大厂面试题

    • 求职建议

    • 面经

  • LearnJavaToFindAJob
  • 【中级】12k-26k档
  • MySQL
#可重复读
码农阿雨
2022-06-02
目录

可重复读是否能解决幻读?

# 可重复读是否解决了幻读?

答案是:大部分情况下解决了,但在特定情况下(锁操作)并未完全解决。

概念 说明
可重复读 (RR) 解决了不可重复读(即一个事务多次读取同一行数据,结果不同)。
幻读 (Phantom Read) 指一个事务多次执行范围查询时,第二次查询的结果集中多出了或少了一些新的/消失的行。

在可重复读的情况下,MySQL 引入 MVCC,但 MVCC 并没有真正解决了幻读。

可重复读开启了间隙锁,而间隙锁解决了幻读。

所以在可重复读下用 间隙锁 或 next key lock 才可以防止幻读。不使用间隙锁是无法解决幻读的。其实在读提交下检测唯一索引的唯一性也会开启间隙锁。

注意,这里说的是针对同一条数据。

如果针对同一个表 但不是同一条数据,那么可以说,不遵循前提条件,嗯,就是间隙锁之外,锁不住的就无法解决幻读问题。在间隙锁之内的,就能解决幻读。

看面试官是否认为这是同一条数据吧。


如何解决幻读?

很明显可重复读的隔离级别没有办法彻底的解决幻读的问题,如果我们的项目中需要解决幻读的话也有两个办法:

  • 使用串行化读的隔离级别
  • MVCC+next-key locks:next-key locks 由 record locks(索引加锁) 和 gap locks(间隙锁,每次锁住的不光是需要使用的数据,还会锁住这些数据附近的数据)

其实幻读也大可不必一定要消除,毕竟幻读也是可以接受的。

但面试中面试官问你如何消除幻读,你回答说 把隔离级别改成 串行化 那是不行的。

# 可重复读的原理

# 1. 核心机制:MVCC (多版本并发控制)

MVCC 允许一个事务读取数据时,看到的是该事务开始时的数据快照,而不是数据最新的修改。这样,即使其他事务正在修改或提交数据,当前事务读取到的数据也不会改变,从而实现了“可重复读”的要求。

MVCC 的主要实现组件:

  • 隐藏列(Hidden Columns) 每个 InnoDB 表的行记录中,都会包含几个重要的隐藏字段:
    • DB_TRX_ID (事务 ID): 记录了对该行数据进行最近一次修改/插入的事务 ID。
    • DB_ROLL_PTR (回滚指针): 指向 undo log 中的一个版本记录。
    • DB_ROW_ID (行 ID): 如果没有主键,InnoDB 会自动生成一个行 ID。

每个事务开始时,系统会生成一个ReadView(一致性视图),ReadView记录当前活跃事务ID列表,用于判断哪些版本对当前事务可见。

# 2. 临键锁(Next-Key Lock) = 记录锁 + 间隙锁

  • 锁定记录本身 + 前面的间隙
  • 默认的行锁算法
  • 既防止当前记录被修改,又有效防止幻影插入

正是这种 “MVCC(用于普通读) + Next-Key Lock(用于加锁读/写操作)” 的组合,使得 InnoDB 的可重复读隔离级别能够有效地避免幻读现象。

阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#可重复读
上次更新: 2026-03-13 10:04:40
最近更新
01
《LeetCode 101》
03-13
02
《LeetCode CookBook》
03-13
03
IDEA、Golang、Pycharm破解安装
03-13
更多文章>
Theme by Vdoing | Copyright © 2020-2026 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式