大白话 Seata 分布式事务浅析,详解TCC模式

article/2025/8/12 10:56:21

大家好,我是此林。

说到分布式事务,第一时间想到 Seata,它支持多种事务模型,比如:XA模式、AT模式、TCC模式、Saga模式(长事务)。

其中 TCC 模式是高性能分布式事务解决方案,适用于核心系统等对 性能有很高要求的场景

不过,相对于 XA 和 AT 无业务入侵的即插即用模式,TCC 是一种 侵入式 的分布式事务解决方案,需要业务系统自行实现 Try,Confirm,Cancel 三个操作,对业务系统有着非常大的入侵性,设计相对复杂。

一、分布式事务

这里贴一张官网的图,其实也就是 Seata 分布式事务的 领域模型,无论是哪种模式(XA、AT、TCC、Saga),都遵循这个模型。

从图中可以看到,三个角色的覆盖级别是:TC > TM > RM

对于Seata 中的

  • TC(Transaction Coordinator)
  • TM(Transaction Manager)
  • RM(Resource Manager)

三者的关系,比难以理解,我们用大白话+代码演示的形式展示。

1. TC事务协调者,我们如果想使用 Seata,是不是需要独立不是 Seata 服务?那这个 Seata 可以简单理解为事务协调中心,即 TC

2. TM事务管理器,可以简单理解为就是 @GlobalTransactional 注解,即全局事务

3. RM资源管理器,这个层级最低,可以理解为标注了@GlobalTransactional 注解的方法下的远程调用 RPC/Feigin 服务分支事务

我们创建一个电商业务,用户下单时:

  1. 扣减库存(库存服务);

  2. 创建订单(订单服务);

  3. 资金支付(账户服务)。

@Service
public class OrderService {@Autowiredprivate InventoryService inventoryService;@Autowiredprivate AccountService accountService;@Autowiredprivate OrderMapper orderMapper;// 这里就是 TM@GlobalTransactional(name = "create_order_tx", rollbackFor = Exception.class)public void createOrder(String userId, String productId, int amount) {// 调用 RM#1 扣减库存inventoryService.deduct(productId, amount);// 调用 RM#2 扣减账户余额accountService.debit(userId, amount * 10);// 插入订单记录(当前服务自己就是 RM)orderMapper.insert(new Order(userId, productId, amount));}
}

可以看到,TM(事务发起方)下,会调用 RM#1 扣减库存,调用 RM#2 扣减账户余额,插入订单记录(当前服务自己就是 RM)。

这样一看是不是关系理清很多了?

二、什么是 TCC 模式?

TCC(Try-Confirm-Cancel)是 Seata 支持的一种 侵入式的分布式事务解决方案,最早由蚂蚁金服提出。

一个分布式的全局事务,整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:

  • 一阶段 prepare 行为
  • 二阶段 commit 或 rollback 行为

AT 模式基于 支持本地 ACID 事务 的 关系型数据库

  • 一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
  • 二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
  • 二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。

相应的,TCC 模式,不依赖于底层数据资源的事务支持:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
  • 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

所以为什么说 TCC 侵入性高?

TCC 服务化的资源管理方式,不依赖于数据库事务,而是由业务系统显式地控制这三个阶段。

XA 和 AT 模式直接使用数据源代理来屏蔽分布式事务细节。

TCC下,业务方需要自行定义 TCC 资源的“准备”、“提交”和“回滚” 。

TCC 三个阶段的含义

阶段说明
Try尝试执行业务,预留必要资源(如扣减库存、锁定额度)
Confirm确认执行业务,真正提交资源(如减库存、扣款)
Cancel回滚业务,释放预留资源,保证幂等

三、TCC 基本使用

我们以一个下单(订单 + 库存)为例子,用 TCC 模式 简化演示。

1. TM 发起全局事务(@GlobalTransactional)

@Service
public class OrderService {@Autowiredprivate InventoryTccAction inventoryTcc;@Autowiredprivate PaymentTccAction paymentTcc;// TM 在这里@GlobalTransactionalpublic void placeOrder(String productId, int count) {inventoryTcc.prepare(null, productId, count); // RM 分支事务1paymentTcc.prepare(null, "userA", 100);       // RM 分支事务2}
}

其中 InventoryTccAction 是库存服务,PaymentTccAction 是支付服务。

2. RM1:库存服务实现 TCC 接口

public interface InventoryTccAction {@TwoPhaseBusinessAction(name = "inventoryTcc", commitMethod = "commit", rollbackMethod = "rollback")boolean prepare(BusinessActionContext ctx, @BusinessActionContextParameter(paramName = "productId") String productId, int count);boolean commit(BusinessActionContext ctx);boolean rollback(BusinessActionContext ctx);
}

3. RM 2:支付服务实现 TCC 接口

public interface PaymentTccAction {@TwoPhaseBusinessAction(name = "paymentTcc", commitMethod = "commit", rollbackMethod = "rollback")boolean prepare(BusinessActionContext ctx, @BusinessActionContextParameter(paramName = "userId") String userId, int amount);boolean commit(BusinessActionContext ctx);boolean rollback(BusinessActionContext ctx);
}

RM 业务接口中核心的注解是 @TwoPhaseBusinessAction,表示当前方法使用 TCC 模式管理事务提交,并标明了 Try,Confirm,Cancel 三个阶段。name属性,给当前事务注册了一个全局唯一的的 TCC bean name。

注意,如果 TCC 参与者是本地 bean(非远程RPC服务),本地 TCC bean 还需要在接口定义中添加 @LocalTCC 注解,比如支付服务是本地的:

@LocalTCC
public interface PaymentTccAction {@TwoPhaseBusinessAction(name = "paymentTcc", commitMethod = "commit", rollbackMethod = "rollback")boolean prepare(BusinessActionContext ctx, @BusinessActionContextParameter(paramName = "userId") String userId, int amount);boolean commit(BusinessActionContext ctx);boolean rollback(BusinessActionContext ctx);
}

4. TM、RM、TC 工作流程图 

5. 注意事项

在旧版Seata,比如小于1.3,为了让 Dubbo/Sofa 的远程调用对象支持 TCC,框架引入了一个类

具体位置:src/main/java/org/apache/seata/spring/tcc/TccAnnotationProcessor.java

@Deprecated
public class TccAnnotationProcessor implements BeanPostProcessor

这个类目前已经被标记为废弃。

那时候框架并不会自动识别是否是 TCC Bean,必须依赖 TccAnnotationProcessor 这个类来扫描注解字段并手动生成代理

不过用法上相比于现在,只不过需要在TM 发起全局事务加上@Reference 注解而已,比如:

@Reference
private PaymentTccAction paymentTcc;

TccAnnotationProcessor主要功能:

  • 在 Spring 启动时扫描 Bean 字段上的 @Reference(Dubbo)或 @SofaReference 注解。

  • 判断其字段类型的方法是否带有 @TwoPhaseBusinessAction

  • 如果带有,则通过反射为该字段注入代理对象。

  • 将该代理对象包装成 TCC RM 支持的形式,注册为资源参与者。

在新版 Seata 里,调用方不需要处理代理,Tcc advice 逻辑移动到了 RM 侧,内置支持 RM 自动识别。

今天的分享就到这里了,

我是此林,关注我吧,带你看不一样的世界!


http://www.hkcw.cn/article/sbAQEikOZQ.shtml

相关文章

超标量处理器设计6-指令解码

1. 指令缓存 指令缓存本质上是一个FIFO, 它能够将指令按照程序中指定的顺序存储起来,这样指令在解码的时候,仍然可以按照程序中指定的顺序进行解码。指令缓存是超标量处理器中必须的部件,其原因有两个: 1. 每周期可以取指的个数大…

技嘉华硕微星主板BIOS开启TPM模块教程

目录 一. TPM模块安装 二. 在BIOS开启TPM功能 华硕主板(Intel平台) 华硕主板(AMD平台) 技嘉主板(Intel平台) 技嘉主板(AMD平台) 微星主板(Intel平台) …

java基础知识

ASCII码 1. next() 示例​​ 读取一个字符串(遇到空格或换行符停止) 运行示例:​​ 输入: 张三 李四 输出: 张三 // 只读取了"张三","李四"留在输入缓冲区

【解决】【亲测下载obsidian可行】打不开github.com 或者 加速访问 github

Windows系统 基本思路:通过修改IP绑定来实现加速访问 1、hosts文件目录 C:\Windows\System32\drivers\etc\hosts2、修改内容 2.1 ping github.com 在Windows的cmd页面下直接输入: ping github.comPS:这一步只是看一下,没在后…

逆向入门(1)

前言: 本篇文章面向想入门逆向的新手小白。 NSSCTF和BUUCTF是两个刷题网站,知识点下面会有对应的题,大家可以自己试着做一下 NSSCTF:https://www.nssctf.cn/problem BUUCTF:https://buuoj.cn/challenges 1.看exe模式(位数&am…

经典算法回顾之最小生成树

最小生成树(Minimum Spanning Tree,简称MST)是图论中的一个重要概念,主要用于解决加权无向图中连接所有顶点且总权重最小的树结构问题。本文对两种经典的算法即Prim算法和Kruskal算法进行回顾,并对后者的正确性给出简单…

Java八股文智能体——Agent提示词(Prompt)

这个智能体能够为正在学习Java八股文的同学提供切实帮助:不仅可以帮你优化答案表述,还能直接解答八股文相关问题——它会以面试者的视角,给出贴合求职场景的专业回答。 将以下内容发送给任何一个LLM,他会按照你提示词的内容&…

VScode编译调试debug,gpu的cuda程序,Nsight

进行下面操作的前提是,我们的环境已经能跑简单的CUDA程序了。 一、安装Nsight 二、创建launch.json文件 {"version": "0.2.0","configurations": [{"name": "CUDA C: Launch","type": "cuda-gdb…

飞牛fnNAS存储空间模式详解

目录 一、NAS的存储空间 二、多硬盘对NAS速度的提升原理 三、多硬盘对数据安全的提升原理 四、多硬盘对容量的提升原理 五、磁盘阵列模式 六、飞牛NAS支持的存储模式 七、具体如何选择存储空间模式 在数字化时代,数据是个人和企业发展的核心资产,但面临硬盘损坏、病毒…

vue3: baidusubway using typescript

项目结构&#xff1a; <!--npm install -D tailwindcss-3d BaiduSubwayMap.vue npm install -D tailwindcss postcss autoprefixer--> <template><div class"relative w-full h-screen"><!-- 地图容器 --><div id"subway-container…

【递归、搜索与回溯】专题二、二叉树中的深搜

文章目录 1.计算布尔二叉树的值1.1 题目1.2 思路1.3 代码 2.求根节点到叶节点数字之和2.1 题目2.2 思路2.3 代码 3.二叉树剪枝3.1 题目3.2 思路3.3 代码 4.验证二叉搜索树4.1 题目4.2 思路4.3 代码 5.二叉搜索树中第K小的元素5.1 题目5.2 思路5.3 代码 6.二叉树的所有路径6.1 题…

Windows商店中的免费扫雷游戏应用

《扫雷》是一款经典的单人益智小游戏&#xff0c;1992年微软发布的Windows 3.1中加入该游戏&#xff0c;从此风靡全世界。游戏目标是通过逻辑推理&#xff0c;在最短的时间内根据点击格子出现的数字找出所有非雷格子&#xff0c;同时避免踩雷。 此Windows应用实现了经典扫雷的…

无法运用pytorch环境、改环境路径、隔离环境

一.未建虚拟环境时 1.创建新项目后&#xff0c;直接运行是这样的。 2.设置中Virtualenv找不到pytorch环境&#xff1f;因为此时没有创建新虚拟环境。 3.选择conda环境&#xff08;全局环境&#xff09;时&#xff0c;是可以下载环境的。 运行结果如下&#xff1a; 是全局环境…

古老的传说(Player、Stage)是否还能在蓝桥云课ROS中重现-250601(失败)

古老的传说是否还能在蓝桥云课ROS中重现-250601 经典复现何其难&#xff0c;百分之二就凉凉&#xff01; 古老的传说 那是很久很久以前的故事……上个世纪的一个机器人项目 Player、Stage这个项目最早起源于1999年&#xff0c;由美国南加州大学机器人研究实验室开发&#xff0…

机器学习:逻辑回归与混淆矩阵

本文目录&#xff1a; 一、逻辑回归Logistic Regression二、混淆矩阵&#xff08;一&#xff09;精确率precision&#xff08;二&#xff09;召回率recall&#xff08;三&#xff09;F1-score&#xff1a;了解评估方向的综合预测能力&#xff08;四&#xff09;Roc曲线&#xf…

Spring是如何实现属性占位符解析

Spring属性占位符解析 核心实现思路1️⃣ 定义占位符处理器类2️⃣ 处理 BeanDefinition 中的属性3️⃣ 替换具体的占位符4️⃣ 加载配置文件5️⃣ Getter / Setter 方法 源码见&#xff1a;mini-spring 在使用 Spring 框架开发过程中&#xff0c;为了实现配置的灵活性&#xf…

继承与多态

继承与多态的分析 继承继承与访问限定比较派生类和基类关系派生类的构造顺序基类对象&#xff08;指针&#xff09;派生类对象&#xff08;指针&#xff09;的转换重载和隐藏 虚函数静态绑定与动态绑定指针调用其他调用的绑定方式虚函数实现的依赖 多态 继承 继承的本质&#…

API异常信息如何实时发送到钉钉

#背景 对于一些重要的API&#xff0c;开发人员会非常关注API有没有报错&#xff0c;为了方便开发人员第一时间获取错误信息&#xff0c;我们可以使用插件来将API报错实时发送到钉钉群。 接下来我们就来实操如何实现 #准备工作 #创建钉钉群 如果已有钉钉群&#xff0c;可以跳…

Amazon GameLift实战指南:低成本构建高并发全球游戏服务器架构

一、为什么游戏服务器需要GameLift&#xff1f; 行业痛点 传统自建服务器&#xff1a;扩容慢、DDoS防御弱、全球延迟不均 开源解决方案&#xff08;如Agones&#xff09;&#xff1a;运维成本高、需K8s深度知识 云虚拟机手动扩缩容&#xff1a;响应延迟导致玩家流失 GameLi…

2025安装与配置archlinux很详细

不知不觉&#xff0c;距离上次安装archlinux已经2年多了。我又打算把archlinux作为主力机使用了。 以前也写过一些类似的文章&#xff0c;有一些不变的内容&#xff0c;我直接从原来的文章中复制了&#xff08;包括截图&#xff09;。 《2021年vmware安装archlinux》 https:/…