以下是 MySQL 支持的四种事务隔离级别及其特性,按并发安全性从低到高排列:
1. 读未提交 (Read Uncommitted)
-
问题:
- 脏读 (Dirty Read):事务可读取其他事务未提交的数据。
- 不可重复读 (Non-repeatable Read):同一事务多次读取同一数据,结果因其他事务提交而不同。
- 幻读 (Phantom Read):事务查询范围时,因其他事务插入/删除数据导致结果集变化。
-
适用场景:对数据一致性要求极低,允许临时性脏数据读取的场景。
2. 读已提交 (Read Committed)
-
问题:
- 不可重复读:事务内多次读取同一数据,可能因其他事务提交修改而结果不同。
- 幻读:仍可能发生。
-
解决方案:
- 只允许读取已提交的数据,通过 行级锁 或 MVCC(多版本并发控制) 避免脏读。
-
适用场景:需避免脏读,但对不可重复读和幻读容忍度较高的场景(如 Oracle 默认级别)。
3. 可重复读 (Repeatable Read)
-
问题:
- 幻读:仍可能因其他事务插入/删除数据导致范围查询结果变化。
-
解决方案:
- 通过 MVCC 快照读 保证事务内多次读取同一数据结果一致。
- 使用 Next-Key 锁(间隙锁+行锁) 减少幻读概率(MySQL 默认级别)。
-
适用场景:需保证事务内多次读取数据一致性的场景(如账户余额查询)。
4. 串行化 (Serializable)
-
问题:
- 性能低下:强制事务串行执行,导致高并发场景下锁竞争和超时。
-
解决方案:
- 通过 表级锁 或 全共享锁 完全禁止并发操作,消除所有并发问题。
-
适用场景:对数据一致性要求极高,且并发量极低的场景。
隔离级别对比与选择建议
隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能影响 |
---|---|---|---|---|
读未提交 | ✔ | ✔ | ✔ | 无 |
读已提交 | ✘ | ✔ | ✔ | 中等 |
可重复读(默认) | ✘ | ✘ | ✔ | 较低(MVCC 优化) |
串行化 | ✘ | ✘ | ✘ | 高(完全串行化) |
选择原则:
- 优先使用默认的 可重复读,平衡一致性与性能。
- 若需严格避免幻读,可升级至 串行化,但需评估性能损耗。
- 通过 显式加锁(如
SELECT ... FOR UPDATE
)补充解决特定场景的并发问题。
验证与设置方法
-
查看当前隔离级别:
SHOW VARIABLES LIKE 'transaction_isolation'; -- MySQL 默认返回 REPEATABLE-READ:ml-citation{ref="8" data="citationList"}
-
修改隔离级别(会话或全局):
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 示例:设置为读已提交:ml-citation{ref="3,8" data="citationList"}
总结
MySQL 的隔离级别通过 锁机制 和 MVCC 实现不同级别的数据一致性保障。开发者需根据业务需求权衡一致性与性能,结合显式锁策略优化高并发场景。