分布式事务的目标不是让远程调用“看起来像一个本地事务”,而是在部分失败后仍守住业务不变量。首选缩小事务边界;确实跨数据所有者时,再按锁定时间、补偿能力和一致性窗口选模式。
Table of contents
Open Table of contents
五种模式
| 模式 | 核心做法 | 适合 | 主要风险 |
|---|---|---|---|
| 2PC/XA | 资源先准备,再统一提交 | 少量支持 XA 的资源 | 阻塞、协调者与资源压力 |
| TCC | 业务实现 Try/Confirm/Cancel | 高价值且可预留资源 | 空回滚、悬挂、幂等成本 |
| Saga | 多个本地事务加反向补偿 | 长流程、可补偿业务 | 中间状态可见、补偿失败 |
| 事务消息 | Broker 协查本地事务结果 | 消息系统支持的发布场景 | 回查与消费仍需幂等 |
| Outbox | 业务数据和事件写同一数据库 | 数据库变更后可靠发事件 | 发布延迟、清理与重复 |
补偿不是数据库回滚。退款可能产生新流水,不能擦掉原付款记录;取消酒店也可能产生手续费。因此补偿动作要有自己的状态、幂等键和人工处理入口。
运行 Outbox 与 Saga
在分布式系统实验室下载执行:
mvn -Dtest=DistributedMechanismsTest#outboxAndIdempotentConsumerSurviveDuplicates test
mvn -Dtest=DistributedMechanismsTest#sagaCompensatesCompletedStepsInReverseOrder test
第一个测试先把事件放入 Outbox,再让消费者处理同一消息两次,余额只增加一次。真实数据库中,业务行与 Outbox 行必须在同一个本地事务提交;发布器成功发送后再标记,崩溃窗口会造成重复,所以消费者仍要幂等。
第二个测试让支付失败,已完成的库存步骤按逆序补偿。生产 Saga 还要持久化每步状态,重启后继续,而不能只把流程存在 Java 调用栈。
选择顺序
先问能否由一个服务和一个数据库完成;再评估异步 Outbox;只有业务必须同步保留资源时考虑 TCC/2PC。任何方案都写清楚最大不一致时间、恢复负责人、对账频率和人工止损方式。
下一步
继续阅读08-11 Seata 工作原理与源码主线,看中间件怎样实现 AT 模式。