# MySql的事务隔离级别
# 为什么有事务隔离级别?
为什么有Mysql有事务的隔离级别?
就像共享文档的协作模式选择:
- 所有人都能看到草稿(读未提交) → 快但乱
- 只能看到已保存的内容(读已提交) → 平衡选择
- 给你文档的截图(可重复读) → 稳定一致
- 锁定文档,一个人改完下一个(串行化) → 最安全但最慢
原因:根本矛盾:隔离 vs 并发
数据库系统面临一个根本性的技术矛盾:
- 强隔离性:保证事务看到一致的数据视图,避免并发异常。
- 高并发性:允许多个事务同时执行,提升系统吞吐量。
隔离级别就是解决这个矛盾的标准化方案。
# 事务的隔离级别
事务的隔离级别有哪几种?实现机制是什么?
| 隔离级别 | 英文 | 脏读 | 不可重复读 | 幻读 | 核心实现机制 | MySQL具体实现 |
|---|---|---|---|---|---|---|
| 读未提交 | Read Uncommitted | ❌ 可能发生 | ❌ 可能发生 | ❌ 可能发生 | 无隔离控制 • 直接读取最新数据页 • 无MVCC版本检查 • 无读锁 | • 直接读取内存中最新的数据版本 • 忽略Undo Log中的旧版本 • 性能最高,一致性最差 |
| 读已提交 | Read Committed | ✅ 防止 | ❌ 可能发生 | ❌ 可能发生 | 语句级快照 • 每条SQL开始时创建快照 • 读取已提交的数据版本 • 使用行锁防止脏写 | • MVCC + Undo Log • 每条SELECT都生成新的Read View • 只读取已提交的事务版本 • 使用记录锁(Record Lock) |
| 可重复读 | Repeatable Read | ✅ 防止 | ✅ 防止 | ⚠️ 部分防止* | 事务级快照 • 事务开始时创建快照 • 整个事务使用同一快照 • 间隙锁防止部分幻读 | • MVCC + Undo Log + 间隙锁 • 事务第一次SELECT时生成Read View • 使用间隙锁(Gap Lock)和临键锁(Next-Key Lock) • MySQL默认级别 |
| 串行化 | Serializable | ✅ 防止 | ✅ 防止 | ✅ 防止 | 完全串行化执行 • 所有读取加共享锁 • 严格的锁协议 • 事务完全串行执行 | • 自动锁升级 • 普通SELECT自动转为SELECT ... LOCK IN SHARE MODE • 使用范围锁和表锁 • 性能最差,一致性最强 |