← 返回题目列表

TCC 模式的原理是什么?Try/Confirm/Cancel 各做什么?

高频 中等 第 9 / 27 题 更新于 2026/07/28
TCC柔性事务补偿

简化版

TCC 是一种业务层面的两阶段补偿型分布式事务,把每个操作拆成三个方法:Try(尝试,预留资源)、Confirm(确认,真正执行)、Cancel(取消,释放预留)。第一阶段所有参与者都执行 Try 预留资源;第二阶段——全成功就都 Confirm 提交,任一失败就都 Cancel 回滚。它把 2PC 的「数据库层锁资源」换成了「业务层预留资源」,不长时间占数据库锁,性能高,但需要每个服务自己实现三个方法,业务侵入大

详细版

以「账户扣款」为例

  • Try:检查余额是否充足,冻结要扣的金额(可用余额 - X,冻结余额 + X)。不是真正扣,是预留。
  • Confirm:真正扣款——把冻结的金额扣掉(冻结余额 - X)。
  • Cancel:解冻——把冻结的金额还回可用余额(可用余额 + X,冻结余额 - X)。

执行流程

  1. 第一阶段:事务管理器调用所有参与者的 Try,各自预留资源。
  2. 第二阶段
    • 所有 Try 都成功 → 调用所有参与者的 Confirm,正式提交。
    • 任一 Try 失败 → 调用所有已 Try 成功者的 Cancel,释放预留。

和 2PC 的对比

  • 2PC 在数据库层锁资源、由 DB 保证,业务无感但锁得久。
  • TCC 在业务层用「冻结」等中间状态预留资源,锁的是业务资源(马上释放 DB 锁),并发高,但要写三个方法。

三大必须处理的问题:空回滚、悬挂、幂等(见专门题目)。

完整版教学

一、TCC 的核心思想:把「锁」变成「预留」

2PC 的问题是数据库锁占用太久(准备到提交全程锁着)。TCC 的巧思是:别锁数据库,改成在业务数据里加一个「预留/冻结」的中间态。Try 阶段做完,数据库事务就提交了(DB 锁马上释放),资源以「冻结」的软状态被预留着。这样即使第二阶段还没来,数据库也不被长时间占用,并发能力大大提升。这本质是用「业务补偿」替代「数据库回滚」,用「软状态冻结」替代「持有锁」。

二、三个方法的职责边界

  • Try做检查 + 预留,不做最终动作。检查业务约束(余额够不够、库存够不够)、预留资源(冻结、扣减可用库存到预留库存)。Try 成功意味着「第二阶段无论 Confirm 还是 Cancel 都不会再失败」——所以检查都放在 Try。
  • Confirm只做真正的业务提交,用 Try 预留的资源。设计上要求 Confirm 不再做业务检查(因为 Try 已经查过、资源已经预留),只管提交,且必须幂等(可能被重试)。
  • Cancel释放 Try 预留的资源,把冻结的还回去。同样要求幂等,且要能处理「Try 没成功却收到 Cancel」的空回滚。

记忆点:Try 负责「一切可能失败的检查与预留」,让 Confirm/Cancel 变成「一定能成功的收尾动作」。这是 TCC 保证第二阶段不失败的关键设计原则。

三、为什么 TCC 性能好

因为 Try 一结束数据库事务就提交了,不像 2PC 那样跨阶段长期持有数据库行锁。资源冲突从「数据库锁」下沉为「业务预留字段」,多个事务可以对同一账户并发做 Try(各自冻结自己那部分),只要总额够就行。所以 TCC 适合高并发、对一致性要求高的资金类场景(支付、账户、优惠券)。

四、代价:业务侵入与复杂度

TCC 不是免费的:

  • 每个参与者要为每个操作写 Try/Confirm/Cancel 三个方法,还要设计冻结/预留字段,改造量大。
  • 要处理空回滚(Try 没执行就收到 Cancel)、悬挂(Cancel 比 Try 先到)、幂等(Confirm/Cancel 被重试)三大边界问题。
  • Confirm/Cancel 要保证最终一定成功(失败要不断重试),所以它们本身必须简单、幂等、无复杂业务判断。

因此 TCC 一般只用在核心的、值得投入改造成本的资金链路,普通业务用 Saga 或可靠消息更划算。

五、TCC vs 2PC vs Saga

维度2PC/XATCCSaga
层面数据库层业务层业务层
资源锁定DB 锁,久业务冻结,短无锁
隔离性有(预留隔离)无(脏读风险)
业务侵入大(三个方法)中(补偿方法)
性能
适用传统强一致资金高一致长流程可补偿

六、常见误区与追问

这道题不能只背概念,要把「TCC 模式」放回真实分布式系统里解释:谁发起、谁协调、状态如何变化、失败后怎么兜底,以及它和性能、可用性、一致性的取舍。

回答层次要讲清的内容容易漏掉的边界
核心结论TCC 把业务操作拆成 Try、Confirm、Cancel,靠业务预留、确认和补偿实现最终一致不要停在名词解释
流程机制Try 预留资源 -> 所有分支 Try 成功 -> 执行 Confirm 完成提交 -> 任一 Try 失败执行 Cancel -> Confirm/Cancel 必须幂等说明触发方、参与方、状态变化和兜底
工程取舍扣款场景 Try 冻结 100 元,Confirm 真扣款,Cancel 解冻 100 元分布式事务没有免费强一致,性能、可用性和业务侵入一定要取舍
TCC 模式 面试拆解:
1. Try 预留资源
2. 所有分支 Try 成功
3. 执行 Confirm 完成提交
4. 任一 Try 失败执行 Cancel
5. Confirm/Cancel 必须幂等

记忆钩子:先说本地事务失效的原因,再拆协调、补偿、消息、幂等、对账和回滚边界;回答时要紧扣「TCC 模式」这道题,不要把相邻概念混成一段泛泛的分布式套话。

  • 误区:TCC 是数据库自动完成的。 TCC 是业务层事务,每个分支都要实现 Try、Confirm、Cancel。
  • 误区:Try 阶段可以直接完成最终扣减。 Try 应预留资源,否则 Cancel 难以安全补偿。
  • 误区:Confirm/Cancel 不会重复调用。 网络重试会导致重复调用,必须幂等。
  • 追问:TCC 三个典型问题是什么? 空回滚、悬挂、幂等。
  • 追问:TCC 适合什么场景? 资金、库存预留等能明确冻结和确认的高一致业务。
  • 追问:TCC 缺点是什么? 业务侵入大,接口数量多,状态管理复杂。

七、加强记忆

TCC = Try/Confirm/Cancel 的业务级两阶段补偿事务。Try 做检查和资源预留(冻结),Confirm 用预留资源真正提交,Cancel 释放预留回滚;一阶段全体 Try,二阶段全成则 Confirm、有败则 Cancel。核心思想是把 2PC 的「数据库锁」换成「业务层冻结软状态」,Try 一结束就释放 DB 锁,因此并发高、适合资金类。代价是要写三个方法、业务侵入大,并必须处理空回滚、悬挂、幂等三大问题;Confirm/Cancel 须幂等且保证最终成功。