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

相关推荐
闲云野鹤在人间1 分钟前
头秃修炼手册:StorageClass+StatefulSet+ETCD 全套渡劫笔记
linux·数据库·笔记·云原生·kubernetes·etcd
ChaITSimpleLove6 分钟前
Layout.WatchDog.NET 1.5.0-beta.2 发布:.NET 实时应用监控再升级,新增资源监控看板与 SQLite 支持
mysql·mongodb·pgsql·mssql·litedb\sqlite·.net轻量级日志记录器·node资源监控看板
Decay__23 分钟前
03_MySQL 存储引擎与存储管理 —— InnoDB 深入、表空间/ibd、binlog/redo/undo 与双写缓冲
运维·数据库·sql·mysql·架构
瀚高PG实验室28 分钟前
瀚高数据库提交数据后,是否需要COMMIT
数据库·postgresql·瀚高数据库
bksczm34 分钟前
MySQL程序架构
数据库·mysql·架构
论文复现现场41 分钟前
2026 低成本 AI Agent 模型怎么选?DeepSeek V4.1 Flash、Qwen3.8 Flash、GLM-5.3 Flash 对比
数据库·人工智能·qwen·ai agent·glm·deepseek
摇滚侠9 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试9 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
2501_9377671610 小时前
自建 SQL 数据库定时备份踩坑复盘与落地思路
数据库·sql
silvamux_11 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记