MySQL 数据库 MVCC 与锁如何联手解决脏读、不可重复读、幻读

MySQL 数据库 MVCC 与锁如何联手解决脏读、不可重复读、幻读

本篇我用 「现象 → 根因 → MVCC 是否能解决 → 需要什么锁」 的方式,把

👉 脏读 / 不可重复读 / 幻读MVCC / 锁机制 一一对上号。

前置说明:

  1. 什么是MVCC?
    参考:《MySQL 数据库 MVCC 机制
  2. 什么是脏读、不可重复读、幻读,及隔离级别?
    参考:《MySQL 数据库 隔离级别 详解
  3. 什么是间隙锁?
    参考:《InnoDB Gap Lock 避坑指南:为什么查不到数据也会锁表?
  4. 什么是 Next-Key Lock ?
    参考:《3 分钟搞懂 Next-Key Lock:原理、触发场景

先给你结论

复制代码
并发现象        能否靠 MVCC 解决        还需不需要锁
---------------------------------------------------
脏读            ✅(最容易)              ❌
不可重复读      ✅(RC / RR)             ❌
幻读            ❌(仅 MVCC 不够)        ✅(Next-Key Lock)

📌 关键记忆点

MVCC 解决 "读旧数据" 的问题;
锁解决 "别人还能不能写" 的问题。


一、脏读(Dirty Read)

现象回顾

读到了 未提交 的数据


根因

  • 没有版本隔离
  • 直接读当前内存中的最新值

MVCC 怎么解决?

✅ 完全可以

  • Read View 只允许读:

    • 已提交事务
    • 自己的事务
text 复制代码
未提交事务 ∈ m_ids → 不可见

👉 自然不会脏读


需要锁吗?

不需要

  • 读历史版本即可
  • 写回滚也不影响读

对应隔离级别

隔离级别 是否可能脏读
RU
RC / RR ✅(MVCC)

二、不可重复读(Non-Repeatable Read)

现象回顾

同一行,两次读结果不同


根因

  • 两次 SELECT 使用了 不同的可见性规则
  • 世界观"变了"

MVCC 怎么解决?

✅ 可以

RC

  • 每条 SELECT 新 Read View
  • 所以 仍可能不可重复读

RR

  • 事务级 Read View
  • 多次 SELECT 看到的是同一个版本

👉 可重复读成立


需要锁吗?

不需要

  • 不要求别人不能改
  • 只是"我想看到一致视图"

对应隔离级别

隔离级别 不可重复读
RC
RR

三、幻读(Phantom Read)

现象回顾

同一条件,两次读到 不同行数


根因(重点)

  • 插入了新行
  • 新行在第一次 SELECT 时根本不存在
  • MVCC 只能决定"看哪个版本",无法阻止新行出现

MVCC 能解决吗?

❌ 只能解决一半

快照读(普通 SELECT)

  • 第二次 SELECT
  • 仍使用原 Read View
  • 看不到新插入行

👉 "看不到幻影"


当前读(FOR UPDATE / UPDATE)

  • 必须读最新数据
  • 不走 MVCC
  • 新行真实存在

👉 幻读仍可能发生


那怎么办?

✅ 必须靠锁

Next-Key Lock = 行锁 + 间隙锁

复制代码
锁住"未来可能插入的位置"
→ 插不进
→ 不会幻读

对应隔离级别

隔离级别 幻读
RC ❌(逻辑可能)
RR(InnoDB) ✅(锁 + MVCC)

四、把三者放到一张"机制对照表"

并发现象 发生在 MVCC 是否足够 锁是否必须
脏读 RU
不可重复读 RC RR 下 ✅
幻读 RC / 标准 RR

五、InnoDB 的终极设计思想

能用 MVCC 解决的,一律不加锁;
MVCC 解决不了的,才用锁;
锁只在"当前读"时才出现。


六、一个终极判断方法

读旧数据 → MVCC;
不让别人改 → 锁;
不让别人插 → Gap / Next-Key Lock。


七、总结

脏读和不可重复读是"看不看历史版本"的问题,
幻读是"新数据能不能出现"的问题,
前者靠 MVCC,后者必须靠锁。

若有转载🧪请标明出处:https://blog.csdn.net/CharlesYuangc/article/details/156310464

相关推荐
wWYy.2 分钟前
Mysql:一行数据是怎么存储的?
android·数据库·mysql
一米阳光86617 小时前
软考(中级)软件设计师核心笔记(3)数据库系统——概念、数据库设计
数据库·笔记·职场发展·软考·软件设计师
奈斯先生Vector7 小时前
告别工具碎片化:基于 Nano Banana 全模态 AI 聚合架构搭建“文本-图像-视频”自动化协同生产线
运维·数据库·人工智能·架构·自动化·aigc·音视频
建筑工程企业管理系统9 小时前
erp工程项目管理系统落地价值:实现工程多项目成本精细化核算与管控
大数据·数据库·人工智能
AI大模型-小华9 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
foolishlee10 小时前
Neon wal日志处理流程2
数据库
2601_9657984711 小时前
Is Hygia Good for Maid & Janitorial Sites? Technical Audit
服务器·网络·数据库
Cloud云卷云舒11 小时前
海山数据库(HaishanDB)面向工业云场景技术方案
数据库·haishandb·工业云·移动云海山数据库·天工云
逃逸线LOF11 小时前
Spring配置数据源{连接池}(Druid、c3p0)
java·数据库·spring
☆凡尘清心☆13 小时前
CentOS Stream 9 专用 LNMP 全自动一键脚本
linux·运维·mysql·nginx·lnmp·centos stream 9