,

数据库事务隔离级别:脏读、不可重复读、幻读、可重复读

前提:事务 ACID,隔离级别就是用来解决这三类问题,MySQL InnoDB 默认隔离级别:REPEATAB…

前提:事务 ACID,隔离级别就是用来解决这三类问题,MySQL InnoDB 默认隔离级别:REPEATABLE‑READ(可重复读)

先准备一张测试表 user

表格

idnamemoney
1A1000

1、脏读 Dirty Read

一个事务读到了另一个事务未提交的数据,对方最后回滚了,读到的数据就是 “脏数据”。

时序:

  1. 事务 B 更新 A 的 money = 0,没有 commit
  2. 事务 A 查询,读到 money=0(读到未提交)
  3. 事务 B rollback 回滚,数据变回 1000
  4. 事务 A 手里拿着一个已经不存在的数据 0 → 脏读
  • 隔离级别:读未提交 (Read Uncommitted) 才会出现脏读
  • MySQL InnoDB 不会出现脏读,最低级别就规避了脏读。

2、不可重复读 Non‑Repeatable Read

同一个事务内,同一条数据,前后两次读取,中间被别的事务修改并提交,两次结果不一样。

时序:

  1. 事务 A:查询 id=1 money=1000
  2. 事务 B:更新 id=1 money=500,commit提交
  3. 事务 A:再次查询同一条 id=1,money 变成 500

同一个事务,两次读同一行,结果变了 → 不可重复读

重点:针对同一行记录,被别的事务修改 / 删除

隔离级别:读已提交 (Read Committed) 会出现不可重复读;可重复读解决不可重复读

⚠注意:不要和幻读搞混。


3、幻读 Phantom Read

同一个事务,前后两次范围查询,别的事务插入 / 删除了新行,导致前后返回行数不一样,像产生了幻影。

时序:

  1. 事务 A:select * from user where money>0,查到 2 条记录
  2. 事务 B:insert 插入一条新记录,commit
  3. 事务 A:再次执行完全一样的 where 范围查询,返回 3 条,多出来一行幻影数据

关键点:不是修改老行,是新增 / 删除行,影响结果集行数

MySQL InnoDB 在 REPEATABLE‑READ(可重复读) 通过 MVCC + Next‑Key Lock(临键锁) 解决了幻读。

其他数据库比如 PostgreSQL,可重复读级别依然存在幻读。


4、可重复读 REPEATABLE‑READ(MySQL InnoDB 默认)

同一个事务内,多次读取,看到的始终是事务启动那一刻的快照,其他事务提交的修改,对当前事务不可见。

依靠 MVCC 多版本并发控制,读快照,不加锁。

特点:

  1. ✅ 杜绝脏读
  2. ✅ 杜绝不可重复读
  3. ✅ InnoDB 下杜绝幻读(临键锁)
  4. 事务开启之后,不管外面别的事务怎么改、新增,我多次查询结果不变。

注意:快照读和当前读区分

普通 select → 快照读 (MVCC,可重复读)

select ... for update → 当前读,拿最新真实数据,会加锁。

四个隔离级别从低到高

表格

隔离级别脏读不可重复读幻读 (InnoDB)
Read Uncommitted 读未提交会发生会发生会发生
Read Committed 读已提交❌不会会发生会发生
Repeatable‑Read 可重复读 (MySQL 默认)❌不会❌不会❌不会 (innodb 临键锁)
Serializable 串行化❌不会❌不会❌不会

隔离级别越高,锁越多,并发性能越低。

面试一句话速记

  1. 脏读:读到别人没提交的数据,对方回滚,拿到脏数据。
  2. 不可重复读:同一行,中间被别人修改提交,事务内两次读结果不一样。
  3. 幻读:范围查询,别人插入 / 删除,返回行数发生变化,多出幻影行。
  4. 可重复读:MySQL InnoDB 默认级别,MVCC 快照,同一个事务多次读取结果保持不变,解决脏读、不可重复读,依靠临键锁解决幻读。

面试高频追问

Q:RC(读已提交)和 RR(可重复读)区别?

  • RC:每次 select 都拿最新快照;会出现不可重复读;锁粒度相对小,并发好。
  • RR:事务启动生成快照,整个事务沿用这份快照;解决不可重复读,InnoDB 解决幻读。

Q:MVCC 是什么?

多版本并发控制,保存数据历史版本,读不加锁,读写不冲突,实现可重复读。

Q:幻读和不可重复读核心区别?

不可重复读:修改 / 删除已有行;

幻读:插入新记录,影响结果集行数。

Previous Post

Next Post

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor