MySQL 事务与四种隔离级别
MySQL 事务与四种隔离级别
为什么需要事务
转账操作:A 扣钱、B 加钱是两条 SQL,中间任何一步失败,钱就凭空消失了。事务保证这一组操作要么全成功,要么全回滚:
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 任一步出错则 ROLLBACK,数据回到事务前
ACID
- 原子性 A:不可分割,失败回滚(靠 undo log)
- 一致性 C:事务前后数据符合约束(是目的,其他三个为它服务)
- 隔离性 I:并发事务之间互不干扰(隔离级别可调节)
- 持久性 D:提交后永久生效(靠 redo log)
并发带来的三种读问题
- 脏读:读到了别的事务还没提交的数据——人家可能回滚,你读到的就是假数据
- 不可重复读:同一事务内两次读同一行,结果不同(中间被别的事务 update 并提交)
- 幻读:同样的条件查询,第二次多出/少了行(被 insert/delete)
四种隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED | 可能 | 可能 | 可能 |
| READ COMMITTED | 避免 | 可能 | 可能 |
| REPEATABLE READ(MySQL 默认) | 避免 | 避免 | InnoDB 下基本避免 |
| SERIALIZABLE | 避免 | 避免 | 避免 |
隔离越强一致性越好,但并发性能越低(SERIALIZABLE 读都加锁)。
InnoDB 的实现:MVCC + 间隙锁
默认的 RR 级别靠 MVCC(多版本并发控制):每行保存历史版本(undo log 链),事务通过 ReadView 看到"自己启动时的快照",所以重复读结果不变,且读写不互斥。幻读则通过 next-key lock(记录锁+间隙锁)锁住查询范围,阻止插入幻影行。
实践建议:
- 多用短事务,减少锁持有时间
- Spring/ORM 里注意 @Transactional 的传播行为和失效场景
- 报表类长查询别放事务里,容易拖垮连接池
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~