基于 Java 实战 TCC 分布式事务之一

大纲

基础概念

多种事务场景

  • 本地事务:一个服务只需要调用一个数据库实例完成数据的增删改查操作


  • 多库事务:一个服务需要调用多个数据库实例完成数据的增删改查操作


  • 跨服务事务:多个服务需要调用同一个数据库实例完成数据的增删改查操作


  • 跨服务事务:多个服务需要调用多个数据库实例完成数据的增删改查操作

TCC 分布式事务的定义

TCC(Try Confirm Cancel)属于补偿型分布式事务(又被称为补偿事务),类似 2PC(两阶段提交)的柔性分布式解决方案,属于 2PC 的改良版。

  • TCC 实现分布式事务一共有三个步骤:

    • Try(尝试待执行的业务):这个过程并未执行业务,只是完成所有业务的一致性检查,并预留好执行所需的全部资源。
    • Confirm(确认执行业务):确认执行业务操作,不做任何业务检查,只使用 Try 阶段预留的业务资源。通常情况下,采用 TCC 则认为 Confirm 阶段是不会出错的。即只要 Try 成功,Confirm 就一定成功。若 Confirm 真的出错了,需引入重试机制或人工处理。
    • Cancel(取消待执行的业务):取消 Try 阶段预留的业务资源。通常情况下,采用 TCC 则认为 Cancel 阶段也是一定成功的。若 Cancel 阶段真的出错了,需引入重试机制或人工处理。
  • 基于 TCC 实现跨银行转账为例:

    • Try 阶段:先冻结两个银行账户中的资金,防止被其他操作使用。
    • Confirm 阶段:执行实际转账,A 银行账户资金扣减,B 银行账户资金增加。
    • Cancel 阶段:若任一操作执行失败,则进行补偿回滚,例如 A 已经扣款但 B 增加资金失败时,就需要将 A 的资金加回去。

  • TCC 事务的优点:

    • 将数据库层的两阶段提交上提到了应用层来实现,规避了数据库层的 2PC 性能低下的问题
    • 可以严格保证事务的最终一致性,尤其适合对最终一致性要求极高的核心业务场景(如支付、交易、资金结算等),并且通常要求各个步骤的执行时间较短
  • TCC 事务的缺点:

    • TCC 的 Try、Confirm 和 Cancel 操作功能需要由业务提供,开发成本高
    • 严重依赖人工编写的补偿逻辑,导致业务代码庞杂、难以维护,因此在实际项目中应用相对较少
  • TCC 事务的适用场景:

    • 对最终一致性要求极高、允许短暂中间状态、但希望不一致窗口尽可能小的核心业务场景,如金融转账、交易、支付结算等
    • 业务链路相对较短、各个业务步骤执行时间可控,能够在较短时间内完成 Try / Confirm / Cancel 的场景
    • 系统能够接受较高的开发与维护成本,且团队具备实现完善的幂等控制、补偿逻辑和异常兜底能力的情况下
  • TCC 两阶段提交与 2PC / XA 的区别:

    • 2PC / XA 是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,会一直持有资源的锁
    • TCC 是业务层面的分布式事务,满足最终一致性,不会一直持有资源的锁
  • 为什么 TCC 可以用于如金融转账、交易、支付等场景:

    • 金融转账、交易、支付系统真正要求的是 “结果零容错”,而不是 “过程零中间状态”。只要中间状态对用户是可理解、可控且可恢复的,系统就能够满足金融级一致性要求。TCC 通过冻结资源与快速补偿机制,将不一致性严格限制在系统内部,并通过业务语义对外提供一致的用户视图,因此在不依赖强一致性事务的前提下,仍然能够保证最终结果绝对正确。
    • 从本质上看,TCC 是一种 “用业务语义模拟强一致性体验” 的最终一致性方案。以银行转账为例,真实的金融系统通常会维护多种账户余额维度(如可用余额、冻结余额、在途金额、已清算 / 未清算金额),总账始终守恒,对用户展示的是业务一致视图。在 TCC 中,Try 阶段只是冻结余额,并不改变最终账务归属;Confirm 阶段才真正完成扣减;Cancel 阶段则会完整回滚冻结。因此,用户看到的是 “处理中” 或 “冻结” 状态,而不是资金凭空消失或异常增加。
    • 在工程实践上,TCC 通过冻结而非直接扣减、同步编排而非纯异步、秒级补偿而非长时间不一致,实现了高可用、可解释且账务绝对正确的交易流程。相比之下,2PC / XA 在金融高并发场景下往往存在资源锁定时间长、对数据库和中间件侵入强、协调者异常容易导致长时间阻塞等问题,极易放大故障风险。而金融系统真正忌讳的是卡死、雪崩和不可恢复的阻塞,而不是短暂且可控的 “处理中” 状态。

特别注意

TCC 属于最终一致性方案,而不是强一致性方案。TCC 适合的不是 "必须强一致" 的场景,而是 "结果绝不能错,但过程可以短暂不一致" 的场景。虽然 TCC 通过 Try-Confirm-Cancel 的同步编排流程,在 Try 阶段预留资源,并在任一参与方失败时立即进入 Cancel,通常可以在秒级内完成一致性恢复,从效果上看 TCC 被认为是最终一致性中 "最接近强一致性" 的方案;但其一致性仍依赖业务层的补偿、重试和幂等机制,允许中间状态短暂存在,无法提供真正意义上的原子提交和瞬时一致性。因此 "接近强一致性" 并不等同于 "强一致性",TCC 其本质仍然是最终一致性解决方案。

TCC 分布式事务的架构

参考资料