首页 > 项目 > 当前页面

分布式事务 TCC 一致性原理详解

2026-06-14 NEW个对象

📌 分布式事务 TCC 一致性原理详解

核心结论:
TCC(Try-Confirm-Cancel)是一种业务层面的分布式事务解决方案,通过资源预留、最终确认、失败回滚三个阶段实现跨服务的数据一致性。相比 XA 两阶段提交,TCC 不依赖数据库锁资源,更适用于高并发互联网系统。

1️⃣ 问题背景

在单体系统中,一个事务往往只涉及一个数据库,通过本地事务即可保证 ACID 特性。

但随着微服务架构的发展,一个业务操作通常会涉及多个服务。例如:

  • 订单服务
  • 库存服务
  • 账户服务
  • 优惠券服务

以电商下单场景为例:

  • 订单创建成功
  • 库存扣减成功
  • 余额扣减失败

此时整个业务处于不一致状态:

订单表:成功
库存表:成功
账户表:失败

如果没有分布式事务机制,就会出现超卖、资金错误、订单异常等问题。

为了解决跨服务事务一致性问题,业界主要出现了:

  • XA 两阶段提交
  • TCC 事务
  • 可靠消息最终一致性
  • Saga 长事务

其中 TCC 是互联网公司使用非常广泛的一种方案。


2️⃣ 核心原理

TCC 全称:

Try(尝试)
Confirm(确认)
Cancel(取消)

其本质思想是:

将数据库层面的事务控制,上升到业务层面控制。

事务协调器负责驱动所有参与者执行:

  • Try
  • Confirm
  • Cancel

整个流程如下:

用户下单


Try阶段
├── 创建订单(待确认)
├── 冻结库存
└── 冻结余额

全部成功?
├── 是 → Confirm
└── 否 → Cancel

如果全部 Try 成功:

  • 正式扣库存
  • 正式扣余额
  • 订单变为已支付

如果任意一个 Try 失败:

  • 释放库存
  • 释放余额
  • 关闭订单

3️⃣ 数据结构分析

库存表设计

sku_id
stock
freeze_stock

库存字段拆分:

  • stock:总库存
  • freeze_stock:冻结库存

例如:

stock=100
freeze_stock=0

Try 阶段:

stock=100
freeze_stock=10

Confirm 阶段:

stock=90
freeze_stock=0

Cancel 阶段:

stock=100
freeze_stock=0

账户表设计

user_id
balance
freeze_balance

余额不会立即扣减,而是先冻结。

事务日志表

tx_no
status
create_time

用于实现幂等控制和事务恢复。


4️⃣ 算法分析

TCC 的核心实际上是状态机。

INIT

TRYING

CONFIRMING

SUCCESS

失败时:

INIT

TRYING

CANCELING

CANCEL_SUCCESS

事务协调器通过记录事务状态驱动整个流程。

其时间复杂度:

Try:O(n)
Confirm:O(n)
Cancel:O(n)

n 表示参与事务的服务数量。


5️⃣ 执行流程

第一步:Try阶段

订单服务调用库存服务:

freezeStock(orderId, skuId, count)

库存服务执行:

update stock
set freeze_stock=freeze_stock+10

账户服务执行:

freezeBalance(userId,money)

冻结余额。

第二步:Confirm阶段

所有 Try 成功后:

stock -= freeze_stock
freeze_stock = 0

余额正式扣减。

订单状态修改为:

PAY_SUCCESS

第三步:Cancel阶段

任意服务失败:

freeze_stock=0
freeze_balance=0

释放所有冻结资源。

⚠️ 注意:Cancel 不一定是失败之后立即执行,很多框架采用异步重试保证最终回滚成功。

6️⃣ 实际案例

电商下单场景

用户余额:

1000元

商品库存:

100件

用户购买:

10件商品
金额200元

Try阶段

冻结库存10件
冻结余额200元
创建待支付订单

Confirm阶段

库存=90
余额=800
订单=支付成功

Cancel阶段

库存恢复100
余额恢复1000
订单关闭

7️⃣ 优缺点分析

✅ 优点

  • 不依赖数据库 XA 协议
  • 性能远高于 XA
  • 不会长期持有数据库锁
  • 适合高并发互联网场景
  • 支持最终一致性
  • 支持跨数据库跨服务事务

❌ 缺点

  • 业务侵入性极强
  • 每个服务都要实现 Try/Confirm/Cancel
  • 开发成本较高
  • 事务状态管理复杂
  • 需要处理幂等、空回滚、悬挂问题
💡 TCC 的最大成本不是技术,而是业务改造成本。

8️⃣ 面试常见问题

TCC 和 XA 的区别?

  • XA 基于数据库锁
  • TCC 基于业务补偿
  • XA 强一致性
  • TCC 最终一致性
  • TCC 性能更高

什么是空回滚?

Try 请求未执行成功,但 Cancel 请求到了。

解决方案:

  • 事务日志记录 Try 状态
  • Cancel 前检查日志

什么是幂等问题?

Confirm 或 Cancel 可能重复调用。

解决方案:

  • 事务号唯一约束
  • 状态机控制
  • 事务日志去重

什么是悬挂问题?

Cancel 已执行完成,但 Try 请求因为网络延迟后来到达。

解决方案:

  • 事务日志记录 Cancel 状态
  • Try 执行前检查事务状态

Seata TCC 如何实现?

Seata 通过:

  • TC(事务协调器)
  • TM(事务管理器)
  • RM(资源管理器)

共同完成 TCC 分布式事务管理。


9️⃣ 总结

📌 TCC 本质:将数据库事务拆分成业务事务。

📌 Try:资源检查并预留资源。

📌 Confirm:真正提交业务操作。

📌 Cancel:释放资源并执行补偿。

📌 一致性保证:通过事务协调器 + 幂等控制 + 空回滚处理 + 防悬挂机制实现最终一致性。

📌 适用场景:订单、支付、库存、账户、优惠券等核心链路。

📌 面试高频结论:TCC 不是数据库层事务,而是业务层事务;其核心思想是“先冻结资源,再确认提交,失败执行补偿”,以最终一致性替代强一致性,从而获得更高的吞吐能力和扩展能力。

相关文章

NEW个对象 NEW个对象
JAVA是世界上最好的语言