① 什么是事务

事务(Transaction)是数据库操作的最小工作单元,包含一条或多条SQL语句,这些语句要么全部成功,要么全部失败回滚。

事务概念示意
🔍 事务的典型场景

最常见的例子是银行转账:A账户扣钱 + B账户加钱,这两步必须作为一个整体—— 要么都成功(A扣了B加了),要么都失败(A没扣B也没加),不能出现A扣了但B没加的中间状态。

-- 转账事务:A向B转账500元 START TRANSACTION; UPDATE accounts SET balance = balance - 500 WHERE id = 'A'; UPDATE accounts SET balance = balance + 500 WHERE id = 'B'; COMMIT; -- 两步都成功,提交 -- 如果任何一步出错:ROLLBACK; (全部回滚)

② 为什么需要事务

没有事务保护,并发操作会导致脏读、不可重复读、幻读等严重数据一致性问题。

无事务 vs 有事务 对比
⚠️ 并发事务的三大问题
问题 描述 后果
脏读 事务A读到了事务B未提交的数据 事务B回滚后,A读到的数据是"脏"的
不可重复读 事务A内两次读取同一数据,结果不一致 事务B在A两次读取之间修改并提交了数据
幻读 事务A两次查询,行数不一致 事务B在A两次查询之间插入或删除了数据

③ ACID 四大特性

ACID 是事务的四大核心特性,缺一不可。点击每个卡片查看详细解释。

A
Atomicity
原子性:事务是最小执行单元,不可分割,要么全做要么全不做
C
Consistency
一致性:事务执行前后,数据库从一个一致状态变到另一个一致状态
I
Isolation
隔离性:并发事务之间相互隔离,不互相干扰
D
Durability
持久性:事务提交后,其结果永久保存,即使系统崩溃也不丢失
🔷 A — Atomicity 原子性详解

原子性Undo Log 保证。

事务对数据的每次修改,都会在 Undo Log 中记录修改前的值。如果事务需要回滚,引擎会沿着 Undo Log 逆向执行,将数据恢复到事务开始前的状态。

④ 事务状态流转

事务从 BEGIN 到 COMMIT/ROLLBACK 经历多个状态,理解状态流转是掌握事务的基础。

⑤ MVCC 多版本并发控制

MVCC(Multi-Version Concurrency Control)是 InnoDB 实现高并发的核心机制,让读写不阻塞

MVCC 版本链原理
📌 MVCC 核心概念
隐藏列
-- 每行记录都有隐藏列: trx_id: -- 最后修改该行的事务ID roll_ptr: -- 指向Undo Log中旧版本的指针
ReadView
-- ReadView 包含: m_ids: -- 当前活跃事务ID列表 min_trx_id: -- 最小活跃事务ID max_trx_id: -- 下一个将分配的事务ID creator_trx_id: -- 创建该ReadView的事务ID

⑥ Undo Log & Redo Log

Undo Log 保证原子性(回滚),Redo Log 保证持久性(崩溃恢复),两者配合实现事务的可靠性。

↩️ Undo Log(回滚日志)

记录数据修改前的版本。事务回滚时,根据 Undo Log 逆向恢复数据。多个版本的 Undo 记录通过 roll_ptr 形成版本链

💾 Redo Log(重做日志)

记录数据修改后的版本。先写 Redo Log(Write-Ahead Logging),再修改内存中的数据页。崩溃后可通过 Redo Log 重做已提交事务的修改。

WAL(Write-Ahead Logging)原理

⑦ 两阶段提交(2PC)

MySQL 使用两阶段提交协议,保证 Redo LogBinlog 两份日志的一致性,是实现崩溃恢复的关键。

🔧 崩溃恢复规则
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 ✅ 解决 ✅ 解决 ✅ 解决 完全串行执行,性能最低

⑨ 知识总结

核心机制对应关系
🔷 原子性Undo Log
🔷 持久性Redo Log + WAL
🔷 隔离性锁 + MVCC
🔷 一致性ACID 协同保证
事务执行流程
1
BEGIN(记录事务ID)
2
执行SQL(写Undo + 改数据页 + 写Redo)
3
COMMIT(两阶段提交)
4
数据落盘(异步刷脏页)
🗺️ MySQL 事务体系全景图