MySQL 数据库 隔离级别 详解
- 一、为什么需要隔离级别?
- [二、MySQL 的 4 种隔离级别(从低到高)](#二、MySQL 的 4 种隔离级别(从低到高))
-
- [1️⃣ READ UNCOMMITTED(读未提交)](#1️⃣ READ UNCOMMITTED(读未提交))
-
- 能看到什么?
- [会出现的问题(或 现象)](#会出现的问题(或 现象))
- [MySQL 实际情况](#MySQL 实际情况)
- [2️⃣ READ COMMITTED(读已提交)⭐常用](#2️⃣ READ COMMITTED(读已提交)⭐常用)
- [3️⃣ REPEATABLE READ(可重复读,MySQL 默认)⭐](#3️⃣ REPEATABLE READ(可重复读,MySQL 默认)⭐)
- [4️⃣ SERIALIZABLE(串行化)](#4️⃣ SERIALIZABLE(串行化))
- [三、4 种隔离级别对比总表(必背)](#三、4 种隔离级别对比总表(必背))
- 四、用一个例子快速理解差异
-
-
- 初始数据
- [事务 A](#事务 A)
- [事务 B](#事务 B)
- [事务 A 再读](#事务 A 再读)
-
- [五、幻读在 MySQL 中是怎么处理的?](#五、幻读在 MySQL 中是怎么处理的?)
- 六、怎么选隔离级别?(实战建议)
- [七、3 句终极理解口诀](#七、3 句终极理解口诀)
- 八、一句话总结
在 MySQL(InnoDB 引擎) 中,事务隔离级别用来规定:
一个事务在执行过程中,能"看到"其他事务做到哪一步的数据
本质是在 一致性(正确性) 和 并发性能 之间做取舍。
下面我用 问题 → 现象 → 机制 → MySQL 实现方式 的方式,进行讲解。
一、为什么需要隔离级别?
如果多个事务同时操作同一批数据,可能出现以下问题:
| 并发现象 | 含义 |
|---|---|
| 脏读 | 读到别人 未提交 的数据 |
| 不可重复读 | 同一行,两次读到 不同值 |
| 幻读 | 同一条件,两次读到 不同行数 |
隔离级别,就是用来控制这些现象允许到什么程度。
二、MySQL 的 4 种隔离级别(从低到高)
1️⃣ READ UNCOMMITTED(读未提交)
能看到什么?
- 能看到别人 还没提交 的数据
会出现的问题(或 现象)
- ❌ 脏读
- ❌ 不可重复读
- ❌ 幻读
MySQL 实际情况
InnoDB 几乎不用,只是标准里有
2️⃣ READ COMMITTED(读已提交)⭐常用
能看到什么?
- 只能看到已提交的数据
- 每次 SELECT 都"刷新视角"
可能出现
- ❌ 不可重复读
- ❌ 幻读(逻辑上)
MySQL 是如何实现的?
- MVCC
- 每条 SELECT 生成新的 Read View
锁行为特点
- 普通 SELECT 不加锁
- 当前读只加 行锁
- 没有 Gap Lock
3️⃣ REPEATABLE READ(可重复读,MySQL 默认)⭐
能看到什么?
- 同一事务中,多次 SELECT 结果一致
解决了什么?
- ✅ 不可重复读
- ✅ 幻读(InnoDB 实现)
MySQL 是如何实现的?
- MVCC(事务级 Read View)
- Next-Key Lock(当前读)
锁行为特点
- 普通 SELECT 不加锁
- 当前读可能锁 行 + 间隙
- 死锁概率略高
4️⃣ SERIALIZABLE(串行化)
能看到什么?
- 事务 像串行执行一样
实现方式
- 普通 SELECT 也会加 S 锁
特点
- 一致性最强
- 并发性能最差
- 实际很少用
三、4 种隔离级别对比总表(必背)
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 实现方式 |
|---|---|---|---|---|
| RU | ❌ | ❌ | ❌ | 几乎不用 |
| RC | ✅ | ❌ | ❌ | MVCC(语句级) |
| RR | ✅ | ✅ | ✅* | MVCC + 锁 |
| SERIALIZABLE | ✅ | ✅ | ✅ | 全锁 |
- RR 在 InnoDB 中通过 Next-Key Lock 防幻读
四、用一个例子快速理解差异
初始数据
balance = 100
事务 A
开启一个事务,然后进行第一次查询。(不提交)
sql
START TRANSACTION;
SELECT balance FROM account; -- 第一次
事务 B
更新数据。(提交)
sql
UPDATE account SET balance = 200;
COMMIT;
事务 A 再读
在之前开启的事务中,进行第二次查询。
sql
SELECT balance FROM account; -- 第二次
对于上述场景,第二次查询结果,在不同的隔离级别中表现如下:
| 隔离级别 | 第二次结果 |
|---|---|
| RU | 200 |
| RC | 200 |
| RR | 100 |
| SERIALIZABLE | 阻塞 |
五、幻读在 MySQL 中是怎么处理的?
RR(默认)
- 快照读:MVCC(看不到新插入)
- 当前读:Next-Key Lock(插不进)
👉 双保险防幻读
RC
- 快照读:MVCC
- 当前读:只锁行,不锁间隙
👉 逻辑上仍可能幻读
六、怎么选隔离级别?(实战建议)
推荐方案
| 场景 | 建议 |
|---|---|
| OLTP 高并发 | RC |
| 金融 / 强一致 | RR |
| 老系统 | RR |
| 分析型 | RC |
📌 越来越多系统选择:
RC + 严格 SQL 规范
七、3 句终极理解口诀
隔离级别,本质是"看世界的方式";
RC 每次刷新世界,RR 世界不变;
越安全,锁越多,并发越差。
八、一句话总结
MySQL 的隔离级别,是通过 MVCC 和锁机制,在一致性与并发性能之间做出的不同权衡。
关于 MVCC 介绍,可参考《MySQL 数据库 MVCC 机制》
若有转载,请标明出处:https://blog.csdn.net/CharlesYuangc/article/details/156258686