← 返回文章列表
数据库·741 次阅读

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 条

还没有评论,来抢沙发~

发表评论

评论需审核后显示

© 2026 许冬博客 · 专注 JS 技术分享

·RSS 订阅·Powered by Nuxt 4