事务与一致性
ACID、本地事务;对照 pg-transactions。
30 分钟
事务与一致性
可靠性 不仅指「服务在线」,还指 数据不错、不丢、不重复。ACID 事务 在 单库 内保证原子性;跨服务则需 Saga、幂等等模式(见 ip-saga)。
学习目标
- 理解 ACID 与本地事务边界
- 知道长事务对可靠性的危害
- 深入 PG 见 pg-transactions
ACID 直觉
| 属性 | 含义 | 违反后果 |
|---|---|---|
| Atomicity | 全成或全滚 | 扣了库存没建订单 |
| Consistency | 约束始终成立 | 负数库存 |
| Isolation | 并发互不干扰 | 脏读、幻读 |
| Durability | 提交后持久 | 重启丢数据 |
CodeRoadMap 用 MySQL + Spring @Transactional,单库内 ACID 由 InnoDB 保证。
本地事务示例
@Transactional
public void enroll(Long userId, Long trackId) {
progressRepo.insert(userId, trackId);
statsRepo.incrementEnrollment(trackId);
// 任一步异常 → 整体 ROLLBACK
}
事务边界 = 一个 @Transactional 方法;调外部 HTTP 不应包在同一事务里——外部失败无法回滚 DB。
可靠性陷阱
长事务持有行锁
→ 阻塞其他请求
→ 连接池耗尽([rel-cascade](/tracks/reliability-essentials/lessons/rel-cascade))
→ vacuum/undo 膨胀(PG 见 pg-transactions)
原则:事务尽量短;只包 DB 操作,IO 放事务外。
跨服务一致性
单体 @Transactional ──► 一个库,强一致
微服务 Saga / 消息 ──► 最终一致 + 补偿
分布式事务(2PC)复杂且慢;业务上多用 Outbox + 消费者幂等(ip-idempotency、ip-messaging)。
宝塔单机注意
MySQL 与 backend 同机,磁盘满 可能导致 commit 失败——备份与磁盘监控是 Durability 的运维保障(prom-alerts)。
练习
- 找出 backend 中一个应缩短事务边界的场景