Seata源码——TCC模式总结

本文介绍了TCC分布式事务协议,包括其工作步骤、优点(如避免长事务锁冲突)、缺点(如复杂度高),并与AT模式对比。重点讲解了Seata如何实现TCC并解决幂等、资源悬挂和空回滚问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是TCC

TCC 是分布式事务中的二阶段提交协议,它的全称为 Try-Confirm-Cancel,即资源预留(Try)、确认操作(Confirm)、取消操作(Cancel)
在这里插入图片描述

TCC的步骤

1.Try:对业务资源的检查并预留
2.Confirm:对业务处理进行提交,即 commit 操作,只要 Try 成功,那么该步骤一定成功
3.Cancel:对业务处理进行取消,即回滚操作,该步骤回对 Try 预留的资源进行释放

TCC的优点

1.TCC的本质原理是把数据库的二阶段提交上升到微服务来实现,从而避免了数据库2阶段中锁冲突的长事务低性能风险。
2.TCC异步高性能,它采用了try先检查,然后异步实现confirm,真正提交的是在confirm方法中。
3.不需要依赖数据库

TCC的缺点

1.设计复杂 使用成本高
2.业务代码侵入大

TCC和AT模式的区别

1、AT需要支持本地 ACID 事务的关系型数据库,TCC不依赖底层数据资源对事务的支持。
2、AT模式使用了全局锁和本地锁,能保证强一致性。TCC只能保证最终一致性。
3、AT模式由于大量使用了锁,吞吐量较低。
4、实现复杂度上,AT模式只需要简单的添加全局事务注解,基本可以实现零侵入,而TCC模式需要自己实现prepare、commit、rollback方法,并考虑空回滚、幂等、悬挂等问题,实现成本较高。

Seata如何实现TCC的

启动阶段

项目启动的时候会设置一个拦截器 专门拦截TCC请求进行处理

Try阶段

当TCC业务执行的时候 会被拦截器拦截
1.创建BusinessContext
2.设置BusinessContext的参数将BusinessContext加入上下文
3.将TwoPhaseBusinessAction注解的参数封装成BranchRegisterRequest请求发给TC注册分支事务
4.TC收到请求进行注册 并且全局事务ID返回给RM 此时这里和AT不同不用加全局锁
5.RM执行try的逻辑

Confirm

1.TM提交全局事务给TC
2.TC收到请求之后执行如下操作:
2.1如果全局事务中存在AT分支事务,先删除AT全局锁;
2.2同步提交TCC分支事务,发送BranchCommitRequest给RM,如果RM响应失败,异步重试至成功为止,如果 成功,删除分支事务;
2.3异步提交AT分支事务,发送BranchCommitRequest给RM,RM异步删除undo_log;
3.RM收到TC发送过来的分支事务提交请求之后通过反射调用 commit方法

Cancel

1.TM回滚全局事务,请求TC
2.TC处理全局回滚
2.1更新global_table全局事务为Rollbacking,如果有AT分支,更新lock_table为Rollbacking
2.2如果有AT分支,释放全局锁lock_table
2.3发送BranchRollbackRequest给RM,如果失败,异步重试至成功为止
2.4如果成功,同步删除branch_table中的分支事务,db/redis模式异步删除global_table全局事务
3.RM收到TC发送过来的回滚请求之后通过反射调用Rollback方法

TCC三大问题

1.幂等:由于网络波动,TC未在超时时间内收到RM二阶段响应,重试导致RM收到多次二阶段rollback或commit请求;
2.资源悬挂:由于网络波动,RM在收到二阶段rollback请求之后,再收到try请求;
3.空回滚:RM由于各种原因未成功执行try,TM回滚全局事务,RM在没有执行try的情况下rollback;

Seata是如何解决TCC三大问题的

在LocalTCC模式下,可以选择开启useTCCFence=true,通过seata框架内置的tcc分支事务状态表解决TCC的三大问题:
1.幂等:RM在try阶段会插入一条STATUS_TRIED状态的分支事务状态记录。收到rollback和commit请求时,RM会通过select for update查询分支事务状态记录,如果状态为STATUS_TRIED才会执行二阶段方法。
2.空回滚:如果rollback和commit时,RM通过select for update查询分支事务状态记录为空,则代表发生空回滚,这里尝试插入一条STATUS_SUSPENDED状态的分支事务记录。如果发生唯一约束冲突,代表try方法被同时执行,返回TC失败,TC会重试;如果没发生唯一约束冲突,返回成功。
3.资源悬挂:由于处理空回滚的时候会插入STATUS_SUSPENDED状态的分支事务记录,RM当rollback后收到try,插入STATUS_TRIED状态记录会发生唯一约束冲突,RM返回TC失败,避免了资源悬挂

参考链接

https://seata.io/zh-cn/docs/dev/mode/tcc-mode

### 谷粒商城 Seata 分布式事务实现与配置 谷粒商城是一个典型的电商系统案例,其架构设计通常涉及多个微服务之间的交互。为了保证跨服务调用的一致性,尤其是订单创建、库存扣减等场景下的强一致性需求,分布式事务成为不可或缺的一部分。 #### 1. **Seata 的引入** Seata 是由蚂蚁金服和阿里巴巴联合开源的分布式事务框架[^1],它提供了 AT 模式(自动补偿模式)、TCC 模式(Try-Confirm-Cancel)、SAGA 模式等多种事务管理方式。其中,AT 模式因其开发成本低、侵入性较小的特点,在实际项目中被广泛采用。 在谷粒商城中,如果选择了 Seata 来解决分布式事务问题,则主要通过以下方式进行集成: --- #### 2. **Seata 配置详解** ##### (1)依赖引入 在项目的 `pom.xml` 文件中,需引入 Seata 的相关依赖: ```xml <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>${seata.version}</version> </dependency> ``` ##### (2)全局事务启动器 在 Spring Boot 应用程序入口类上添加注解 `@EnableDistributedTransaction` 或者直接启用 Seata 提供的默认支持机制。 ##### (3)数据库表初始化 Seata 需要在数据库中预先创建用于记录事务日志的相关表格。可以通过执行官方提供的 SQL 脚本来完成这一操作。例如: ```sql CREATE TABLE IF NOT EXISTS `undo_log` ( -- 表字段定义省略... ); ``` 该表主要用于存储回滚所需的元数据信息。 ##### (4)配置文件调整 修改 `application.yml` 中关于 Seata 的具体参数设置: ```yaml spring: cloud: alibaba: seata: tx-service-group: my_tx_group # 定义事务组名称 server: port: 8081 ``` 同时还需要指定 TM(事务协调器)以及 RM(资源管理器)的服务地址等相关细节。 --- #### 3. **源码分析** 以下是基于 Seata 的典型业务逻辑处理流程的一个简化版本说明: 假设有一个下单接口 `/order/createOrder`,涉及到两个远程服务——订单服务和库存服务之间协作完成整个交易过程。 ###### 订单服务端代码片段 ```java @Service public class OrderService { @Autowired private RemoteStockService stockService; /** * 创建订单并减少对应商品数量 */ public void createOrder(Order order) { try (GlobalTransactional transactional = new GlobalTransactional()) { // 开启全局事务 transactional.begin(); saveOrder(order); // 存储本地订单信息至数据库 boolean result = stockService.decreaseStock(order.getProductId(), order.getCount()); if (!result) throw new RuntimeException("库存不足"); transactional.commit(); // 显式提交成功后的更改 } catch (Exception e) { log.error("订单创建失败", e); // 自动触发回滚动作 } } private void saveOrder(Order order) { // 数据库保存逻辑 } } ``` 上述例子展示了如何利用 Seata 的 API 将原本独立的操作封装成一个整体单元来保障原子性特性。 --- #### 4. **BASE 理论的应用背景** 尽管 Seata 力图提供 ACID 特性的分布式事务解决方案,但在大规模高并发环境下完全遵循传统关系型数据库的标准可能带来性能瓶颈。此时 BASE 理念便显得尤为重要[^3]。通过对最终一致性的容忍度提升,能够显著改善系统的吞吐量表现。 例如,在谷粒商城的实际运行过程中,当面对大量促销活动引发瞬时流量激增的情况时,可以适当放宽部分非核心链路的要求,优先确保用户体验流畅的同时逐步收敛后台数据差异直至达成预期目标。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值