第七章:事务
1. 事务的价值
事务(Transaction)把一组读写操作封装成一个原子单元,目标是在故障与并发环境下给应用提供可控语义,减少“部分成功”带来的状态爆炸。
2. ACID 的工程含义
2.1 原子性(Atomicity)
事务要么全部提交,要么全部回滚。实现依赖 WAL、回滚日志或多版本机制。
2.2 一致性(Consistency)
ACID 里的一致性本质是“业务不变量成立”,主要由应用与约束共同保障,数据库只能提供检查与执行框架。
2.3 隔离性(Isolation)
并发事务互不干扰的程度。理想目标是可串行化,但实际常在性能与隔离之间折中。
2.4 持久性(Durability)
提交成功后,数据在崩溃后可恢复。单机依赖持久化日志,分布式依赖复制与恢复协议。
3. 多对象事务为何仍重要
单对象原子操作(如 CAS)无法覆盖跨行、跨表、跨索引约束。以下场景通常需要多对象事务:
- 外键与唯一约束维护。
- 多记录共同更新。
- 二级索引与主数据同步更新。
4. 常见隔离级别与异常
4.1 Read Committed
避免脏读与脏写,但仍可能出现不可重复读与幻读。
4.2 Snapshot Isolation
事务从一致快照读取,读写互不阻塞,常通过 MVCC 实现。可显著提升读性能,但仍可能发生写偏差。
4.3 丢失更新(Lost Update)
典型 read-modify-write 并发覆盖问题。优先方案:
- 原子更新语句。
SELECT ... FOR UPDATE。- 自动冲突检测并重试。
UPDATE account
SET balance = balance - 100
WHERE id = 1;
4.4 写偏差与幻读
写偏差是“读取同一前提、更新不同对象”导致的不变量破坏,常由幻读触发。仅靠快照隔离通常不能完全避免。
5. 可串行化实现路线
5.1 串行执行(Serial Execution)
单线程按顺序执行事务,语义最直接。适合高性能内存场景,但跨分区事务代价高。
5.2 两阶段锁(2PL)
通过共享锁与排他锁实现悲观并发控制,可实现可串行化,但会带来阻塞、死锁与延迟抖动。
5.3 可串行化快照隔离(SSI)
基于快照隔离运行,在提交期检测危险依赖并中止冲突事务。读性能通常优于 2PL,是现代关系库常用折中。
6. 实务建议
- 默认隔离级别不等于业务安全级别,关键路径要显式验证并发语义。
- 以“可重试事务 + 幂等接口”设计上层逻辑。
- 对高争用热点优先重构数据模型,避免把所有问题都压给锁。