在分布式系统中,保证跨多个服务的事务一致性是核心挑战之一。传统单机环境下的 ACID 事务(原子性、一致性、隔离性、持久性)无法直接适配分布式场景,因此诞生了多种分布式事务解决方案。TCC和Saga是其中两种典型的模式,主要用于解决分布式环境下的事务一致性问题。
一、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 适合长事务、步骤多的业务,通过补偿机制实现最终一致性,开发成本较低但需容忍中间状态。
在实际应用中,需根据业务对一致性的要求、复杂度和性能需求选择合适的模式,甚至结合其他方案(如本地消息表、事务消息)共同使用。