① 什么是事务
事务(Transaction)是数据库操作的最小工作单元,包含一条或多条SQL语句,这些语句要么全部成功,要么全部失败回滚。
最常见的例子是银行转账:A账户扣钱 + B账户加钱,这两步必须作为一个整体—— 要么都成功(A扣了B加了),要么都失败(A没扣B也没加),不能出现A扣了但B没加的中间状态。
② 为什么需要事务
没有事务保护,并发操作会导致脏读、不可重复读、幻读等严重数据一致性问题。
| 问题 | 描述 | 后果 |
|---|---|---|
| 脏读 | 事务A读到了事务B未提交的数据 | 事务B回滚后,A读到的数据是"脏"的 |
| 不可重复读 | 事务A内两次读取同一数据,结果不一致 | 事务B在A两次读取之间修改并提交了数据 |
| 幻读 | 事务A两次查询,行数不一致 | 事务B在A两次查询之间插入或删除了数据 |
③ ACID 四大特性
ACID 是事务的四大核心特性,缺一不可。点击每个卡片查看详细解释。
原子性由 Undo Log 保证。
事务对数据的每次修改,都会在 Undo Log 中记录修改前的值。如果事务需要回滚,引擎会沿着 Undo Log 逆向执行,将数据恢复到事务开始前的状态。
④ 事务状态流转
事务从 BEGIN 到 COMMIT/ROLLBACK 经历多个状态,理解状态流转是掌握事务的基础。
⑤ MVCC 多版本并发控制
MVCC(Multi-Version Concurrency Control)是 InnoDB 实现高并发的核心机制,让读写不阻塞。
⑥ Undo Log & Redo Log
Undo Log 保证原子性(回滚),Redo Log 保证持久性(崩溃恢复),两者配合实现事务的可靠性。
记录数据修改前的版本。事务回滚时,根据 Undo Log 逆向恢复数据。多个版本的 Undo 记录通过 roll_ptr 形成版本链。
记录数据修改后的版本。先写 Redo Log(Write-Ahead Logging),再修改内存中的数据页。崩溃后可通过 Redo Log 重做已提交事务的修改。
⑦ 两阶段提交(2PC)
MySQL 使用两阶段提交协议,保证 Redo Log 和 Binlog 两份日志的一致性,是实现崩溃恢复的关键。
| Redo Log 状态 | Binlog 状态 | 恢复操作 |
|---|---|---|
| Prepare | 无记录 | 回滚事务(Undo) |
| Prepare | 有完整记录 | 提交事务(Redo commit) |
| Commit | 有完整记录 | 无需处理(已提交) |
⑧ 事务隔离级别
SQL 标准定义了四种隔离级别,级别越高数据一致性越强,但并发性能越低。MySQL 默认隔离级别是 REPEATABLE READ。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | MVCC ReadView |
|---|---|---|---|---|
| READ UNCOMMITTED | ❌ 可能 | ❌ 可能 | ❌ 可能 | 无MVCC,直接读最新数据 |
| READ COMMITTED | ✅ 解决 | ❌ 可能 | ❌ 可能 | 每次查询都生成新的 ReadView |
| REPEATABLE READ(默认) | ✅ 解决 | ✅ 解决 | ⚠️ 部分解决 | 事务开始时生成一次 ReadView |
| SERIALIZABLE | ✅ 解决 | ✅ 解决 | ✅ 解决 | 完全串行执行,性能最低 |