分布式事务头疼?一文讲透TCC与Saga的救赎之道!

434 阅读6分钟

在分布式系统中,保证跨多个服务的事务一致性是核心挑战之一。传统单机环境下的 ACID 事务(原子性、一致性、隔离性、持久性)无法直接适配分布式场景,因此诞生了多种分布式事务解决方案。TCCSaga是其中两种典型的模式,主要用于解决分布式环境下的事务一致性问题。

一、TCC 模式

TCC 是 Try-Confirm-Cancel 的缩写,是一种基于 “业务侵入式” 的分布式事务解决方案,核心思想是通过拆分事务为三个阶段,实现资源的预留与确认,从而保证最终一致性。

1. 核心思想

将一个分布式事务拆分为三个明确的操作阶段,通过手动编码实现资源的检查、确认和回滚,确保事务的原子性。

2. 三个核心阶段

  • Try(尝试阶段)
    主要负责 资源检查 和 资源预留

    • 检查业务所需的资源是否可用(如库存是否充足、账户余额是否足够)。
    • 对资源进行 “预占用”(如冻结部分库存、锁定账户余额),确保后续操作能顺利执行,且不被其他事务干扰。
      注意:Try 阶段的操作必须是幂等的(重复执行结果一致),避免因网络重试导致资源重复预留。
  • Confirm(确认阶段)
    当 Try 阶段所有服务都执行成功后,进入确认阶段,负责 实际执行业务操作 并释放预留资源。

    • 将 Try 阶段预留的资源正式提交(如扣减冻结的库存、转账锁定的金额)。
    • 此阶段操作需确保最终成功(通过重试等机制),因为一旦进入 Confirm,意味着事务已无法回滚。
  • Cancel(取消阶段)
    若 Try 阶段有任何服务执行失败,进入取消阶段,负责 回滚资源预留,恢复到事务执行前的状态。

    • 释放 Try 阶段预留的资源(如解冻库存、解锁账户余额)。
    • 同样需要保证幂等性,避免重复取消导致资源异常。

3. 实现特点

  • 业务侵入性强:需要在业务代码中手动实现 Try/Confirm/Cancel 三个方法,与具体业务逻辑深度耦合。
  • 一致性强:通过资源预留机制,可实现接近 ACID 的强一致性(但非严格 ACID)。
  • 性能较好:无全局锁阻塞,各阶段可并行执行,适合高频核心业务。
  • 开发复杂度高:需设计严谨的资源预留逻辑和幂等性处理,且 Cancel 逻辑需完全抵消 Try 阶段的影响。

4. 适用场景

  • 核心高频业务(如支付、转账、库存扣减),对一致性要求极高。
  • 业务逻辑简单、资源类型明确的场景(如账户余额、库存等可量化资源)。

示例:转账场景

  • Try 阶段:检查转出账户余额是否充足,冻结转出金额;检查转入账户状态正常。
  • Confirm 阶段:扣减转出账户冻结金额,增加转入账户金额,释放冻结资源。
  • Cancel 阶段:解冻转出账户冻结金额,恢复原始状态。

二、Saga 模式

Saga 模式源于 1987 年的数据库论文,核心思想是将一个长事务拆分为多个短事务(本地事务),每个短事务对应一个 “补偿事务”,通过执行补偿事务回滚已完成的操作,最终保证事务一致性。

1. 核心思想

将分布式事务分解为一系列本地事务步骤(每个步骤由单个服务独立完成,满足本地 ACID),并为每个步骤定义对应的补偿步骤(用于回滚该步骤的影响)。若某个步骤执行失败,按相反顺序执行前面所有步骤的补偿操作,最终恢复到事务开始前的状态。

2. 执行流程

  • 正常流程:按顺序执行各本地事务步骤(Step 1 → Step 2 → ... → Step N),全部成功则事务完成。
  • 异常流程:若 Step K 执行失败,触发补偿机制,按相反顺序执行补偿步骤(Compensate K-1 → Compensate K-2 → ... → Compensate 1),撤销已执行步骤的影响。

3. 实现方式

Saga 模式有两种主流实现方式,核心区别在于 “流程协调” 的责任方:

实现方式核心逻辑优点缺点
Choreography(编排式)无中心协调者,每个服务通过事件通知触发下一个服务的执行,失败时由服务自身触发补偿。去中心化,灵活性高,无单点依赖。流程逻辑分散在各服务中,复杂流程难以维护,排查问题困难。
Orchestration(编排式)引入一个 “协调者(Orchestrator)”,由协调者统一管理事务流程,决定下一步执行或补偿。流程逻辑集中,易维护,适合复杂流程。协调者可能成为单点瓶颈,需保证协调者的高可用。

4. 实现特点

  • 业务侵入性低:无需修改原有本地事务逻辑,只需新增补偿事务(如 “创建订单” 对应 “取消订单”,“扣减库存” 对应 “恢复库存”)。
  • 一致性较弱:属于最终一致性,事务执行过程中可能存在中间状态(如 “订单已创建但库存未扣减”)。
  • 性能较好:无资源锁定,各步骤异步执行,适合长事务场景。
  • 补偿逻辑复杂:需确保补偿事务能完全抵消原步骤的影响,且补偿操作本身需幂等(避免重复补偿导致数据异常)。

5. 适用场景

  • 长事务场景(如订单履约:创建订单→扣库存→支付→物流→通知,步骤多且跨服务)。
  • 对一致性要求不严格,但需保证最终状态正确的业务(如电商订单、供应链流程)。
  • 业务逻辑复杂、步骤多,且难以实现资源预留的场景。

示例:电商订单流程

  • 正常步骤:创建订单(Step 1)→ 扣减库存(Step 2)→ 支付(Step 3)→ 通知用户(Step 4)。
  • 异常补偿:若支付失败(Step 3 失败),则执行补偿:恢复库存(Compensate 2)→ 取消订单(Compensate 1)。

三、TCC 与 Saga 的对比

维度TCC 模式Saga 模式
一致性强一致性(接近 ACID)最终一致性(存在中间状态)
业务侵入性高(需手动实现 Try/Confirm/Cancel)低(只需新增补偿事务)
开发复杂度高(资源预留和幂等设计复杂)中(补偿逻辑需严谨)
适用场景核心高频、短事务、强一致性需求长事务、步骤多、最终一致性需求
性能高(无锁阻塞,并行执行)高(异步执行,无资源锁定)
中间状态无(资源预留阶段不暴露中间结果)有(步骤执行中可能出现中间状态)

总结

TCC 和 Saga 都是分布式事务的重要解决方案,核心目标是在分布式环境下保证事务的最终一致性,但适用场景和实现方式差异显著:

  • TCC 适合对一致性要求极高的核心业务,通过资源预留实现强一致性,但开发成本高;
  • Saga 适合长事务、步骤多的业务,通过补偿机制实现最终一致性,开发成本较低但需容忍中间状态。

在实际应用中,需根据业务对一致性的要求、复杂度和性能需求选择合适的模式,甚至结合其他方案(如本地消息表、事务消息)共同使用。