1053 字
约 3 分钟
5
S11-B06 · 事务与隔离级别
2024-12-31
2026-11-07

适用读者:被"脏读/不可重复读/幻读"绕晕的人。
前置:S11-B05。
实测环境:MySQL 8.0.46 / InnoDB(默认隔离级别,2026-11-05)。
覆盖旧文:1234(48) 848(94) 1235(80) 1731(126) 1735(129) 1567(538) = 1,015 点。
覆盖扩展:E-S11-006(MVCC 与快照读)。
上一篇:S11-B05 · 索引基础:类型、结构与最左前缀
下一篇:S11-J01 · 回表与覆盖索引。


1. 一句话结论

隔离级别是"用一致性和并发度做交换的旋钮"。MySQL 默认 REPEATABLE READ,靠 MVCC 在"读"上实现一致性,靠锁在"写"上防冲突。

隔离级别 脏读 不可重复读 幻读
READ UNCOMMITTED ✅ 会 ✅ ✅
READ COMMITTED ❌ ✅ 会 ✅
REPEATABLE READ(默认) ❌ ❌ ⚠️ 快照读不下、当前读靠间隙锁
SERIALIZABLE ❌ ❌ ❌(全串行)

2. 实测:可重复读到底"重复"在哪

会话 A(开启事务):

begin; select age from t_user where id=1;   -- 读到 1
       select sleep(6);                     -- 等待
       select age from t_user where id=1;   -- 再读
commit;

会话 B(2 秒后):

update t_user set age=99 where id=1; commit;

实测输出:

@@transaction_isolation = REPEATABLE-READ
会话 A 第一次读: 1
会话 B: 更新已提交,age = 99
会话 A 第二次读: 1        ← 仍然读到 1

结论:会话 A 在同一个事务里两次读到相同的值——即使 B 已提交。这就是"可重复读",靠 MVCC 快照实现(不是靠锁)。


3. MVCC:为什么能"读到旧值"(E-S11-006)

组件 作用
隐藏列 DB_TRX_ID 最后一次修改的事务 ID
隐藏列 DB_ROLL_PTR 指向 undo 里的旧版本
Read View 事务开始时确定"哪些事务可见"
查询 → 取当前行 → 若 DB_TRX_ID 在 Read View 里"不可见"
     → 沿 rollback pointer 找旧版本 → 直到找到可见版本

"快照读"与"当前读"的区别:

类型 例子 是否走 MVCC
快照读 普通 select ✅ 读快照
当前读 select ... for update、update、delete ❌ 读最新(加锁)

这解释了"为什么加了 for update 就能看到别人的提交"。


4. 幻读与间隙锁

幻读:同一事务两次范围查询,第二次多出新行。

场景 InnoDB 行为
快照读 MVCC 保证看不到新行(不算幻读)
当前读(for update) 用**间隙锁(gap lock)**阻止插入

判据:"我的业务依赖"范围查询结果不变"吗?" 依赖 → 用 for update 或提高隔离级别。


5. 事务的四个特性与代价

特性 靠什么
原子性 A undo log
一致性 C 约束 + 应用逻辑
隔离性 I MVCC + 锁
持久性 D redo log

长事务的代价:undo 膨胀、锁持有时间长、主从延迟(A-2659)——"事务里别做 RPC" 是最实用的建议。


6. 五个误区

误区 真相
"RR 靠锁实现" 读靠 MVCC,写靠锁
"RR 完全没幻读" 快照读没有;当前读靠间隙锁
"隔离级别越高越好" 并发度下降、锁竞争加剧
"长事务只影响自己" undo 膨胀 + 拖慢主从
"for update 也是快照读" 是当前读

7. 自检

  1. 四个隔离级别分别解决什么?
  2. 实测里会话 A 第二次读到几?为什么?
  3. MVCC 靠哪两个隐藏列 + 什么机制?
  4. 快照读与当前读的差别?
  5. 长事务的三个代价?

8. 下一篇

S11-J01 · 回表与覆盖索引

事务讲完,进阶层开始:为什么 select * 比 select 主键 慢,以及覆盖索引怎么省掉回表。


本篇属于系列《S11 · 数据库与 SQL》。旧文来源:A-1234/848/1235/1731/1735/1567;扩展点 E-S11-006。可重复读对照为 MySQL 8.0.46 实测(两会话)。

S11-B06 · 事务与隔离级别
https://www.clxhxhhr.top/posts/5330/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。