跳转到内容

分布式事务方案选型

用途:面对一个具体的跨资源场景,快速决定用哪种方案

四个问题决定方案,缺一个就无法选型:

  1. 参与方是否都可控?(自己团队的服务 vs 外部机构)
  2. 能容忍多长的不一致窗口?(0 秒 / 秒级 / 分钟级 / 日终)
  3. 是否存在“资源预留”语义?(额度、库存、席位可冻结)
  4. 流程时长与是否含人工环节?(毫秒级 vs 跨天审批)
方案 一致性 可用性 侵入性 运维复杂度 典型场景
同库本地事务(调整边界) 强 高 无 低 首选:能把强一致部分收进一个聚合/一个库
2PC / XA 强 低 低 高 参与者少且可控、绝不允许不一致
TCC 接近强 中 高(三接口) 中 资金/资源预留、要求快速反馈
Saga 最终 高 中(补偿) 中 长流程、含人工、多服务
本地消息表 / Outbox 最终 高 低 中 内部事件投递,需可审计重放
事务消息 最终 高 中(回查) 中 依赖 RocketMQ 类中间件
最大努力通知 弱 高 低 中 对接外部机构
定时任务 + 对账 最终 高 低 低 兜底与修复,任何方案都需要
  1. 先消除需求:重新划分聚合与数据所有权,让强一致操作落在同一资源内。这一步的收益通常大于任何框架选型。
  2. 再选最终一致:内部跨服务默认 Outbox 或事务消息 + 消费幂等 + 对账。
  3. 有预留语义才考虑 TCC;流程长或含人工才考虑 Saga。
  4. 2PC/XA 只在参与者极少且必须强一致时使用,并明确协调者故障处理策略。
  5. 外部机构一律最大努力通知 + 主动查询 + 对账,不要假设对方可靠。

无论选哪种都必须具备的四件事

「无论选哪种都必须具备的四件事」小节链接
  • 幂等(业务键而非消息 ID)
  • 状态机守卫(禁止旧数据覆盖新状态)
  • 可观测(在途量、失败率、延迟、卡点)
  • 对账与人工兜底通道
误区 修正
先选框架再想场景 先问能否通过边界设计消除跨库需求
混用多种方案却无人负责一致性 每条链路明确一致性目标与负责方案,写进设计文档
只测正向流程 补偿与对账路径的测试覆盖要高于正向
用“最终一致”掩盖无界延迟 给出不一致窗口上限并监控实际收敛时间
忽略用户感知设计 中间态需要明确文案与可操作性(“处理中”不可重复提交)
  • Chris Richardson《微服务架构设计模式》第 4、8、9 章
  • Martin Kleppmann《数据密集型应用系统设计》第 7–9 章
  • Pat Helland《Life beyond Distributed Transactions》