事务的 ACID 如何理解?MySQL 的隔离级别与实现手段是什么?

结论先行:ACID 是事务正确性的四个性质:原子性、一致性、隔离性、持久性。InnoDB 的实现分工清晰:原子性靠 undo log,持久性靠 redo log,隔离性靠 MVCC + 锁,一致性靠约束与前三者共同保证;MySQL 默认隔离级别是可重复读(RR)。

一、ACID 与对应实现

性质含义InnoDB 靠什么保证
A 原子性要么全成功要么全回滚undo log:失败时撤销已做修改
C 一致性数据始终满足约束与业务规则约束 + AID 共同作用,应用层也参与
I 隔离性并发事务互不干扰MVCC 快照读 + 锁(当前读)
D 持久性提交后不丢失redo log 预写 + 刷盘

二、四种隔离级别

隔离级别脏读不可重复读幻读说明
读未提交 RU可能可能可能基本不用
读已提交 RC不会可能可能Oracle 默认
可重复读 RR不会不会可能(可被间隙锁避免)MySQL 默认
串行化不会不会不会加锁范围大,性能低
  • 脏读:读到其它未提交事务的数据。
  • 不可重复读:同一事务两次读同一条记录结果不同(针对行更新)。
  • 幻读:同一事务两次范围查询多出/少了行(针对插入)。

三、MVCC、快照读与当前读

  • 快照读(普通 SELECT):走 undo 版本链 + 读视图,不加锁;RR 下整个事务用同一份快照。
  • 当前读(UPDATE/DELETE/SELECT ... FOR UPDATE):读最新版本并加锁。
  • RR 下当前读用 next-key lock(行锁 + 间隙锁)封住范围,从机制上消除幻读。

四、事务语句与加锁快查

语句读类型加锁情况
SELECT(普通查询)快照读不加锁
SELECT ... FOR UPDATE当前读行锁 + 间隙锁
UPDATE / DELETE当前读行锁 + 间隙锁

常见追问与记忆点

  • 追问:为什么 MySQL 默认 RR 而不是 RC?历史兼容:早期 statement 格式 binlog 下 RC 会主从不一致,RR 对开发者也更安全。
  • 追问:大厂为什么常改成 RC?并发写冲突少、间隙锁开销低,配合 row 格式 binlog 无主从不一致风险。
  • 记忆点:原子靠 undo、持久靠 redo、隔离靠 MVCC + 锁;隔离级别读问题从 RU 到串行化逐级变少。
笔记加载中…