★ 分布式事务有哪些方案?2PC、TCC、本地消息表与最终一致性怎么选?

结论先行:分布式事务没有"银弹",核心是在一致性与可用性之间做取舍:2PC/XA 追求强一致但同步阻塞、性能差;TCC 把事务拆成 Try/Confirm/Cancel 三阶段,业务侵入大但灵活;本地消息表与消息事务走最终一致,适合高并发互联网场景。工程上 90% 以上的业务用最终一致方案加对账兜底即可。

一、主流方案对比

方案原理优点缺点场景
2PC / XA先 Prepare 再 Commit,协调者统一决策强一致同步阻塞、协调者单点、性能差少用,传统单库扩展
TCCTry 预留、Confirm 确认、Cancel 补偿无锁、可控性强侵入业务、需防悬挂与空回滚账务、库存等核心链路
本地消息表业务与消息同库事务,异步投递实现简单通用与业务库耦合、需定时补投一般业务最终一致
可靠消息事务半消息 + 回查(RocketMQ 事务消息)解耦、消息可靠依赖 MQ 能力订单、积分等场景
Saga长事务拆子事务,失败反向补偿适合长流程无隔离性、补偿复杂跨系统长流程编排
Seata AT基于全局锁与 undo log 自动回滚对业务侵入小依赖框架与性能开销单体拆分过渡期

二、TCC 的典型三阶段

Try:    预留资源,例如冻结库存、预占金额
Confirm:业务确认成功,把预留转为实际扣减
Cancel: 业务失败或超时,释放预留回滚资源
注意:Confirm/Cancel 必须幂等,且要处理 Try 成功但 Confirm 丢失导致的悬挂问题
悬挂防护:Try 成功后 Confirm 长时间未到,需定时任务对账后决定补 Confirm 或触发 Cancel

三、选型与兜底

  • 强一致且低并发:才考虑 2PC 类方案,多数互联网场景无法接受其阻塞与性能;
  • 高并发最终一致:优先本地消息表或事务消息,再叠加消费幂等;
  • 通用兜底三件套:幂等设计、对账任务、人工补偿入口,任何分布式事务方案都离不开;
  • 本地消息表误区:消息要等消费方确认后才标记完成,未确认的靠定时任务补投,而不是发完即删;
  • 2PC 的真实定位:跨数据库强一致且事务量小的内部系统仍会用到,互联网核心链路基本不用;
  • 面试表达顺序:先给结论"默认最终一致",再按强一致到弱一致介绍方案矩阵,最后落到幂等与对账;
  • 对账任务设计:对账以业务单据为维度核对各系统终态,差额走补偿流程,是最终一致方案的最后一环;
  • 事务消息细节:半消息要配回查接口供 Broker 探活,回查失败要有告警与人工处理路径,防止消息永久悬挂。

常见追问 / 记忆点

  • 追问:2PC 的协调者挂了怎么办?答:参与者会一直阻塞等待,需协调者高可用与超时决议机制,这是它最大的痛点。
  • 追问:TCC 的 Confirm 和 Cancel 会被调用多次吗?答:会,网络重试下可能重复调用,所以两者必须幂等。
  • 追问:最终一致要多长时间?答:秒级到分钟级,超过阈值由对账任务兜底修正。
  • 记忆点:XA 强一致但笨重,TCC 靠三阶段补偿,最终一致方案 = 可靠消息 + 消费幂等 + 对账。
笔记加载中…