← 返回软件技术总览 软件技术 · 知识点深化 · 事务与 ACID:隔离级别、幻读/不可重复读、MVCC
知识点深化 · 数据库 · 事务

事务与 ACID:隔离级别、幻读/不可重复读、MVCC

事务是一组要么全成功要么全失败的操作。ACID 里最复杂的是隔离性:多个事务并发时会有脏读、不可重复读、幻读。四种隔离级别逐级解决,而 InnoDB 用 MVCC 多版本实现读写不阻塞。这一页讲透。

① 小白第一课怎么学(4 步走,约 60 分钟)

别急着背代码,先按这四步建立直觉:

1看图建立直觉(10 分钟)
读②③:并发事务互相干扰。
2记隔离级别(15 分钟)
读④:四种级别对应三种现象。
3手推现象(20 分钟)
精读⑤。
4刷题纠错(15 分钟)
做⑦⑩,错题回⑥。
本课小目标学完你要能:① 说清四种隔离级别解决什么问题;② 区分脏读/不可重复读/幻读;③ 解释 MVCC。

② 一图看懂:事务与隔离全地图

事务 ACID A 原子性 全成或全败 C 一致性 数据约束不破 I 隔离性 并发互不干扰 D 持久性 提交后落盘 隔离级别:读未提交→读提交 →可重复读→串行化 MVCC 多版本,读写不阻塞 undo log + ReadView
读法:中心是事务 ACID,右隔离级别,下是 MVCC 与易错。

③ 本质直觉:并发事务像两个人同时改同一本账

三种读现象:① 脏读:读到别的事务还没提交的修改;② 不可重复读:同一事务内两次读同一行,值不一样(被别的事务改了);③ 幻读:同一事务内两次范围查询,行数变了(别的事务插入了新行)。

四种隔离级别:读未提交(啥都防不住)→ 读提交 RC(防脏读)→ 可重复读 RR(防脏读+不可重复读,InnoDB 默认)→ 串行化(全防,最慢)。

MVCC:每行存多个历史版本(undo log),读的时候按 ReadView 选一个可见版本,读写不互相阻塞——这就是 InnoDB 高并发的秘密。

隔离级别越高,越安全越慢 读未提交:脏读/不可重复/幻读 全有 读提交 RC:防脏读 可重复读 RR:防前两个 串行化:全防 InnoDB 默认 RR,MVCC 下基本防幻读 MySQL 默认 RR,Oracle 默认 RC
不可重复读 vs 幻读不可重复读是同一行被 update(值变了);幻读是范围查询多了/少了行(insert/delete)。

④ 完整体系与对比表

四种隔离级别与现象

隔离级别脏读不可重复读幻读
读未提交 RU有有有
读提交 RC无有有
可重复读 RR无无有(标准)/InnoDB基本无
串行化无无无

MVCC 原理

每行隐藏两列:trx_id(最后修改的事务 ID)、roll_pointer(指向 undo log 上的旧版本)。读时生成 ReadView,按规则判断哪个版本可见。这样读快照、写最新,读写不锁不阻塞。

RC vs RR 的 ReadViewRC 每次 SELECT 都生成新 ReadView(能看到别的已提交);RR 只在第一次 SELECT 生成(整个事务看到同一快照)

⑤ 用法场景与典型例题

例1(脏读)事务 A 改了余额未提交,事务 B 读到新值,A 又回滚,B 读到什么?
这是脏读。
B 读到了未提交的值,A 回滚后那值就不存在了。要读提交 RC 以上才能避免。
例2(不可重复读)RR 下事务内两次读同一行,中间别人改了并提交,结果?
RR 保证快照。
RR 下两次读看到的是同一快照版本,结果相同,避免了不可重复读。
例3(默认级别)MySQL InnoDB 默认隔离级别?
可重复读。
REPEATABLE READ。Oracle/PostgreSQL 默认 RC。
做题心法记现象:脏读=读未提交的脏数据;不可重复读=同行值变;幻读=行数变。级别逐级加锁/MVCC。

⑥ 高频错误诊断(4 条)

错误1:混淆不可重复读和幻读不可重复读针对 update(行值变);幻读针对 insert/delete(行数变)。
错误2:以为 RR 完全防幻读标准 RR 仍可能幻读;InnoDB 用间隙锁/Next-Key Lock 在很大程度上防住了。
错误3:以为隔离级别越高越好串行化并发差,按业务选。大多数互联网用 RC。
错误4:MVCC 是为了写更快MVCC 是让读写不阻塞、读不阻塞写,提升并发读。

⑦ 考点真题演练(4 题)

考点分布

考法出题形式应对
现象脏读/不可重复/幻读定义区分
隔离级别对应防什么背表
默认级别MySQL InnoDBRR
MVCC读写不阻塞原理undo+ReadView

真题基础1. 一个事务读到了另一个事务尚未提交的修改,叫?

真题中档2. MySQL InnoDB 默认的隔离级别是?

真题中档3. 同一事务内两次范围查询结果集行数不同,是因为别的事务插入了行,这叫?

真题拔高4. MVCC 实现读写不阻塞依赖?

⑧ 必背知识点卡

A 原子:全成或全败
C 一致:约束不破
I 隔离:并发互不干扰
D 持久:提交落盘
脏读:读未提交 RC 解决
不可重复:同行值被改 RR 解决
幻读:行数变了 串行化/间隙锁
MVCC:undo 多版本+ReadView 读写不阻塞

⑨ 应用输出:设计账户转账事务

场景:A 给 B 转账 100 元,要扣 A 加 B 同时成功或同时失败。
① 开启事务:begin。
② 扣 A:update account set balance=balance-100 where name='A'。
③ 加 B:update account set balance=balance+100 where name='B'。
④ 提交:两步都成功 commit;任一步失败 rollback,A 不会少钱。
⑤ 并发:默认 RR 下两个并发转账不会互相脏读;MVCC 保证读写不阻塞。
口述思路合上书说:"转账就是一个事务包两步 update,失败回滚,隔离级别默认 RR。"

⑩ 分层练习(基础 + 中档 + 拔高)

▍基础 6 题

基础1ACID 是什么?
原子、一致、隔离、持久。
基础2脏读读的是什么?
别的事务未提交的数据。
基础3MySQL InnoDB 默认隔离级别?
可重复读 RR。
基础4不可重复读是什么?
事务内两次读同行值不同。
基础5幻读是什么?
范围查询行数变了。
基础6最高隔离级别?
串行化。

▍中档 6 题

中档7RC 能防脏读吗?
能,RC 只读已提交数据。
中档8MVCC 中文叫什么?
多版本并发控制。
中档9undo log 在 MVCC 里干嘛?
存数据旧版本,供 ReadView 回溯。
中档10RC 和 RR 的 ReadView 区别?
RC 每条 select 新建;RR 第一次 select 建。
中档11串行化怎么防幻读?
事务排队执行,串行无并发。
中档12事务 ACID 里哪项由锁和 MVCC 保障?
隔离性 I。

▍拔高 6 题

拔高13Next-Key Lock 是什么?
行锁+间隙锁,锁住索引记录和间隙,防幻读。
拔高14什么是丢失更新?
两事务同时改一行互相覆盖,要用乐观锁/悲观锁。
拔高15乐观锁怎么实现?
加 version 字段,update where version=旧值。
拔高16MVCC 一定不用锁吗?
写操作仍加锁;读快照不加锁。
拔高17为什么互联网常用 RC 而不是 RR?
RC 并发更高,避免长事务快照 undo 链过长。
拔高18redo log 和 undo log 区别?
redo 保证持久性(先写日志),undo 保证原子性+MVCC 旧版本。

⑪ 记忆口诀 + 7 天复习计划

三句口诀① 原子一致隔离持久,隔离级别逐级防。② 脏读读未提交,不可重复同行变,幻读行数变。③ MVCC 多版本读写不阻塞,InnoDB 默认 RR。
天任务自检
第 1 天读②③④,画隔离级别阶梯现象对应对
第 2 天背 ACID + 基础 1-6三种现象分清
第 3 天做中档 7-12,讲 ReadViewRC/RR 区别对
第 4 天做拔高 13-18,讲 Next-Key Lock能讲清防幻读
第 5 天做⑦真题 4 题限时每题 2 分钟
第 6-7 天合上书默写隔离级别表不看资料全默对

← 返回软件技术总览