一句话定义
事务(Transaction)是把一组读写操作封装为「要么全做、要么全不做」的执行单元,由 ACID 四性质保证:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
为什么重要
- 转账「扣款成功、入账失败」这类资金事故的免疫机制就是事务,它是数据库对应用最核心的价值承诺。
- ACID 四个字母分别由不同机制支撑(回滚段、约束、锁/MVCC、WAL),知道「谁保证哪一条」才能在故障时正确定位。
- 事务边界划在哪,直接决定锁持有时间、死锁概率与吞吐,是每个后端工程师每天要做的决策。
前置知识
kp-004(基本 DML)。
核心概念
- 原子性:事务内操作不可分割,失败即整体回滚(由 Undo 日志/回滚段实现)。
- 一致性(C):事务把数据库从一个一致状态带到另一个一致状态(由约束 + A/I/D 共同达成,C 是目标不是机制)。
- 隔离性:并发事务互不观察对方的中间状态(由锁/MVCC 实现,强度分级见 kp-015)。
- 持久性:提交即落盘,断电不丢(由 WAL 与 fsync 实现,见 kp-020)。
- 事务语句:
BEGIN/START TRANSACTION、COMMIT、ROLLBACK、保存点(SAVEPOINT)。 - 自动提交:未显式开事务时每条语句自成事务。
原理与机制
生命周期:BEGIN 后事务获得唯一 ID,写入先进缓冲池并记日志;COMMIT 的关键动作是「把 redo 日志刷到磁盘」(组提交可将多个事务合并一次 fsync),此后即使数据页尚未写盘、机器断电,恢复流程也能重放日志补齐(持久性);ROLLBACK 则用 Undo 日志反向补偿已做的修改(原子性)。保存点允许部分回滚:长事务内设检查点,出错只撤到 SAVEPOINT。事务边界的工程含义:事务越长,持有锁越多、Undo 越大、复制延迟越敏感;因此「把远程调用、大计算移出事务」是铁律。Spring 的 @Transactional 等框架注解只是自动包一层 BEGIN/COMMIT,注解范围错误(把整个 HTTP 处理器包成事务)是高频线上事故。
实例或案例
转账两步的原子性:
BEGIN;
UPDATE accounts SET balance = balance - 100
WHERE user_id = 1 AND balance >= 100;
-- 若上一句影响行数为 0,说明余额不足,应 ROLLBACK
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;
COMMIT;
应用侧必须检查第一条 UPDATE 的受影响行数,为 0 时执行 ROLLBACK——余额检查放进 WHERE 让「判断与扣减」原子化,避免检查与扣减之间被并发插入。
常见误区
- 把一致性当作自动保证:数据库只保证约束不被违反,业务级一致(如「总库存 = 各仓之和」)要靠事务设计。
- 事务里调外部接口(发短信、调支付):远程调用把事务拖到秒级,锁与连接池双双耗尽。
- 认为 MySQL 默认就是自动回滚一切错误:许多错误(死锁)只回滚当前语句而非整个事务,应用必须显式处理。
自测题
- 四个性质分别由哪些机制支撑? 答:A 由 Undo/回滚段,I 由锁与 MVCC,D 由 WAL+fsync,C 由前三者与约束共同实现(C 是结果目标)。
- 为什么长事务危险? 答:锁持有时间变长抬高死锁与阻塞概率;Undo 链变长拖慢 MVCC 清理与回滚;复制与备份的一致点被推迟。
公式或模型
本节不适用:本知识点是性质定义与边界工程学,定量模型在 kp-016(死锁)、kp-022(缓冲池)出现。
图示
直观类比
事务像一场婚礼仪式:交换戒指的每个动作(扣款、入账)要么全部完成(COMMIT)、证婚有效且永久记录(WAL),要么在「我愿意」之前任何环节出错就整体不算(ROLLBACK),绝无「只完成一半的婚礼」。
与其他知识点的关系
kp-015 把隔离性展开为分级模型与异常复现;kp-016、kp-017 是实现隔离性的两条技术路线;kp-020 揭示 A 与 D 的日志机制;kp-018 把 ACID 延伸到跨节点场景。
延伸阅读
- Jim Gray《The Transaction Concept: Virtues and Limitations》(VLDB 1981)
- 《Transaction Processing: Concepts and Techniques》(Gray & Reuter,1993)