当前位置: 首页 > article >正文

为什么 MySQL InnoDB 的 Repeatable Read 可以阻止幻读?

为什么 MySQL InnoDB 的 Repeatable Read 可以阻止幻读?

首先,幻读(Phantom Read) 指的是:在同一个事务内,前后两次执行相同的查询,第一次查询不到的行,第二次查询时却出现了

例如:

  1. 小明查询 SELECT * FROM users WHERE age > 20,返回 5 条数据。
  2. 小红在另一个事务里插入一条 INSERT INTO users VALUES (21岁用户) 并提交。
  3. 小明再查询,发现结果变成 6 条!这就是幻读。

在标准 SQL 定义下,可重复读(Repeatable Read) 只保证「同一事务内,对已存在的数据读到的内容不变」,但新插入的数据仍然可能影响查询结果,所以一般可重复读不能解决幻读

然而,MySQL 的 InnoDB 通过「间隙锁(Gap Lock)」在可重复读级别下额外解决了幻读问题


InnoDB 如何阻止幻读?—— 间隙锁(Gap Lock)

Gap Lock(间隙锁) 是 InnoDB 的Next-Key Lock 机制的一部分。它不仅锁住「已有的数据行」,还会锁住「数据之间的间隙」,从而防止新的插入。

示例:用间隙锁阻止幻读
  1. 小明启动事务 BEGIN;
  2. 小明执行 SELECT * FROM users WHERE age > 20 FOR UPDATE;
    • InnoDB 发现这里是范围查询,于是加上间隙锁,不仅锁住已有的 age > 20 的用户,还会锁住这些用户之间的「空隙」。
  3. 小红想插入 INSERT INTO users VALUES (21岁用户),但发现被锁住了,必须等小明的事务提交后才能继续。

💡 这样,MySQL InnoDB 通过锁住「数据之间的间隙」,让新的插入无法发生,从而避免了幻读!


总结

  • 标准 SQL 的 Repeatable Read 不能阻止幻读,但 MySQL InnoDB 通过「间隙锁(Gap Lock)」实现了这个能力
  • 间隙锁会锁住「查询范围内的数据 + 数据之间的间隙」,防止新的数据插入,从而避免了「前后两次查询看到的结果不一致」。
  • 但间隙锁可能影响并发性能,因为它会锁住较大的范围,使得插入操作被阻塞。

➡️ 这就是为什么 MySQL InnoDB 的 Repeatable Read 级别下「不会发生幻读」的原因!


http://www.kler.cn/a/578307.html

相关文章:

  • 【JavaEE进阶】Spring AOP详解
  • preloaded-classes裁剪
  • 工业单板电脑在电商物流中心的应用案例
  • Java多线程与高并发专题——什么是阻塞队列?
  • Windows CMD 命令大全(综合开发整理版)
  • 【编译器】VSCODE搭建ESP32
  • C++:dp3则
  • 数据库---1.0
  • 基于SpringBoot的餐厅点餐管理系统设计与实现(源码+SQL脚本+LW+部署讲解等)
  • 【redis】全局命令set、get、keys
  • typora高亮方案+鼠标侧键一键改色
  • 解决https页面请求http出现Mixed Content.This request has been blocked; the content must be served over HTTPS.
  • vscode - 操作整理
  • WPS的付费功能,这款软件可完美平替
  • 推荐一款性价比高的nas产品?
  • 深入理解 HTML 元素:构建网页的基础
  • 【极光 Orbit•STC8A-8H】03. 小刀初试:点亮你的LED灯
  • 小程序 wxml 语法 —— 40 列表渲染-基本用法
  • STM32——定时器
  • 服务器上通过ollama部署deepseek