240813-分布式事务解决方案Seata之TCC事务

TCC事务

TCC(Try-Confirm-Cancel)是分布式事务中性能最好、控制粒度最细,但开发成本最高的模式。

一、TCC 核心原理

TCC 将业务逻辑拆分为三个阶段,需要开发者手动实现三个接口:

流程如下:

  1. Try 阶段(尝试/预留)
    做什么:检查业务资源,预留/冻结资源。
    例子:冻结账户余额(不扣减)、锁定库存(不扣减)。
    要求:幂等、允许失败。
  2. Confirm 阶段(确认/执行)
    做什么:真正使用 Try 阶段预留的资源。
    例子:扣除已冻结的余额、扣减已锁定的库存。
    要求:必须成功(如果 Try 成功,Confirm 不应该失败,否则需要人工介入),幂等。
  3. Cancel 阶段(取消/回滚)
    做什么:释放 Try 阶段预留的资源。
    例子:解冻余额、释放锁定库存。
    要求:幂等。
1
2
3
4
5
6
7
8
9
10
  [TM 全局事务]
|
+-----v-----+
| Try (预留) | <--- 所有分支 Try 成功后,进入 Confirm
+-----+-----+ 任一分支 Try 失败,进入 Cancel
|
+-----v-----+ +-----+-----+
| Confirm | | Cancel |
| (执行) | | (回滚) |
+-----------+ +-----------+

二、TCC vs AT 模式对比

特性 AT 模式 (Seata 默认) TCC 模式
侵入性 无侵入 (SQL 解析) 高侵入 (需改业务代码,写 3 个方法)
一致性 最终一致性 (依赖 undo_log) 最终一致性 (依赖业务补偿)
隔离性 全局锁 (读写冲突) 无全局锁 (业务隔离)
性能 一般 (高并发下有锁竞争) 高 (适合高并发)
开发成本 低 (加注解即可) 高 (需处理幂等、空回滚、悬挂)
适用场景 内部微服务,中低并发 核心链路,高并发,跨语言

三、使用场景

不要为了炫技而用 TCC。 请遵循以下决策路径:

  1. 首选 AT 模式:90% 的场景,AT 模式足够用,开发快,维护成本低。
  2. 遇到性能瓶颈时:如果 AT 模式的全局锁导致数据库并发上不去(例如秒杀、热点账户),再考虑 TCC。
  3. 核心资金链路:支付、转账等场景,需要业务层面的精细控制(如冻结资金),TCC 更合适。
  4. 非 Java 语言:如果事务参与者包含 Go/Python 服务,AT 模式(依赖 Java SQL 解析)无法使用,必须用 TCC。

四、TCC代码实战

4.1 配置依赖

各个微服务引入

1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

4.2 代码入口添加全局事务

入口

1
2
3
4
5
6
@GlobalTransactional
@Override
public void process(EventMessageReq eventMessageReq) {
// 委托给 WarnInfoService 处理完整的业务逻辑
deviceEventService.processDeviceEvent(eventMessageReq);
}

被调用方

1
2
3
4
5
6
7
8
9
@TwoPhaseBusinessAction(name = "doSave", // 动作名称,全局唯一
commitMethod = "confirm", // Confirm 方法名
rollbackMethod = "cancel" // Cancel 方法名
)
boolean doSave(@BusinessActionContextParameter(paramName = "saveDto") SysOperLogPO saveDto);

boolean confirm(BusinessActionContext context);

boolean cancel(BusinessActionContext context);

4.3 接口测试

发送测试报文,可以看到seata server 日志信息

测试报文

#
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×