隔离级别
hardMySQL隔离级别脏读不可重复读幻读
并发事务的三大问题
| 问题 | 描述 | 示例 |
|---|---|---|
| 脏读 | 读到另一个事务未提交的修改 | A 修改数据但未提交,B 读到修改后的数据,A 回滚 → B 读到了不存在的数据 |
| 不可重复读 | 同一事务内两次读取同一行,结果不同 | B 读取 x=100,A 更新 x=200 并提交,B 再读 x=200 |
| 幻读 | 同一事务内两次查询,记录数不同 | B 查询 age>20 得到 3 条,A 插入一条 age=25,B 再查得到 4 条 |
四种隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | InnoDB 实现 |
|---|---|---|---|---|
| 读未提交 (RU) | ✅可能 | ✅可能 | ✅可能 | 不加锁,直接读最新数据 |
| 读已提交 (RC) | ❌ | ✅可能 | ✅可能 | MVCC,每次 SELECT 创建新 Read View |
| 可重复读 (RR) | ❌ | ❌ | ❌* | MVCC,事务首次 SELECT 创建 Read View 并复用 |
| 串行化 (S) | ❌ | ❌ | ❌ | 读加共享锁,写加排他锁 |
InnoDB 默认隔离级别是可重复读(RR),并且通过 MVCC + 间隙锁在 RR 级别下也很大程度解决了幻读问题。
RC vs RR 的核心区别
RC(读已提交):
事务 B 的每次 SELECT 都生成新的 Read View
→ 能看到其他事务在此期间的提交 → 不可重复读
RR(可重复读):
事务 B 第一次 SELECT 生成 Read View,之后复用
→ 看不到其他事务后续的提交 → 可重复读
生产高频题
MySQL 的默认隔离级别是什么?
可重复读(Repeatable Read),通过 MVCC 实现。RC 和 RR 的区别在于 Read View 的创建时机:RC 每次查询新建,RR 首次查询创建后复用。
InnoDB 的 RR 级别能完全解决幻读吗?
快照读(普通 SELECT)通过 MVCC 解决了幻读;当前读(SELECT ... FOR UPDATE)通过间隙锁(Gap Lock)阻止其他事务在范围内插入新记录,也能解决幻读。但特殊场景(先快照读再当前读)可能仍有幻读。