分布式事务方案选型
用途:面对一个具体的跨资源场景,快速决定用哪种方案
决策输入
「决策输入」小节链接四个问题决定方案,缺一个就无法选型:
- 参与方是否都可控?(自己团队的服务 vs 外部机构)
- 能容忍多长的不一致窗口?(0 秒 / 秒级 / 分钟级 / 日终)
- 是否存在“资源预留”语义?(额度、库存、席位可冻结)
- 流程时长与是否含人工环节?(毫秒级 vs 跨天审批)
方案对照表
「方案对照表」小节链接| 方案 | 一致性 | 可用性 | 侵入性 | 运维复杂度 | 典型场景 |
|---|---|---|---|---|---|
| 同库本地事务(调整边界) | 强 | 高 | 无 | 低 | 首选:能把强一致部分收进一个聚合/一个库 |
| 2PC / XA | 强 | 低 | 低 | 高 | 参与者少且可控、绝不允许不一致 |
| TCC | 接近强 | 中 | 高(三接口) | 中 | 资金/资源预留、要求快速反馈 |
| Saga | 最终 | 高 | 中(补偿) | 中 | 长流程、含人工、多服务 |
| 本地消息表 / Outbox | 最终 | 高 | 低 | 中 | 内部事件投递,需可审计重放 |
| 事务消息 | 最终 | 高 | 中(回查) | 中 | 依赖 RocketMQ 类中间件 |
| 最大努力通知 | 弱 | 高 | 低 | 中 | 对接外部机构 |
| 定时任务 + 对账 | 最终 | 高 | 低 | 低 | 兜底与修复,任何方案都需要 |
推荐顺序
「推荐顺序」小节链接- 先消除需求:重新划分聚合与数据所有权,让强一致操作落在同一资源内。这一步的收益通常大于任何框架选型。
- 再选最终一致:内部跨服务默认 Outbox 或事务消息 + 消费幂等 + 对账。
- 有预留语义才考虑 TCC;流程长或含人工才考虑 Saga。
- 2PC/XA 只在参与者极少且必须强一致时使用,并明确协调者故障处理策略。
- 外部机构一律最大努力通知 + 主动查询 + 对账,不要假设对方可靠。
无论选哪种都必须具备的四件事
「无论选哪种都必须具备的四件事」小节链接- 幂等(业务键而非消息 ID)
- 状态机守卫(禁止旧数据覆盖新状态)
- 可观测(在途量、失败率、延迟、卡点)
- 对账与人工兜底通道
常见误区
「常见误区」小节链接| 误区 | 修正 |
|---|---|
| 先选框架再想场景 | 先问能否通过边界设计消除跨库需求 |
| 混用多种方案却无人负责一致性 | 每条链路明确一致性目标与负责方案,写进设计文档 |
| 只测正向流程 | 补偿与对账路径的测试覆盖要高于正向 |
| 用“最终一致”掩盖无界延迟 | 给出不一致窗口上限并监控实际收敛时间 |
| 忽略用户感知设计 | 中间态需要明确文案与可操作性(“处理中”不可重复提交) |
延伸阅读
「延伸阅读」小节链接- Chris Richardson《微服务架构设计模式》第 4、8、9 章
- Martin Kleppmann《数据密集型应用系统设计》第 7–9 章
- Pat Helland《Life beyond Distributed Transactions》