Seata架构篇 - TCC模式
TCC 模式
概述
TCC 是分布式事务中的两阶段提交协议,它的全称为 Try-Confirm-Cancel,即资源预留(Try)、确认操作(Confirm)、取消操作(Cancel)。Try:对业务资源的检查并预留;Confirm:对业务处理进行提交,只要 Try 成功,那么该步骤一定成功;Cancel:对业务处理进行回滚,对 Try 预留的资源进行释放。
TCC 是一种侵入式的分布式事务解决方案,以上三个操作都需要业务系统自行实现,对业务系统有着非常大的侵入性,设计相对复杂,但优点是完全不依赖数据库,能够实现跨数据库、跨应用的资源管理,对这些不同数据的访问通过侵入式的编码方式实现一个原子操作,更好解决了各种复杂业务场景下的分布式事务问题。
TCC 模式最大的优势是效率高。在 try 阶段的锁定资源并不是真正意义上的锁定,而是提交了本地事务,将资源预留到中间状态,不需要阻塞等待,因此效率比其它模式更高。而且采用异步提交的方式,try 阶段执行成功后,启动定时任务异步执行 confirm/cancel 方法。
Seata TCC模式1.5.1版本的优化
代码演示
假设现在有一个业务需要同时使用服务 A 和服务 B 完成一个事务操作。
对服务 A 定义一个 TCC 接口:
public interface TccActionOne {@TwoPhaseBusinessAction(name = "DubboTccActionOne", commitMethod = "commit", rollbackMethod = "rollback")public boolean prepare(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "a") String a);public boolean commit(BusinessActionContext actionContext);public boolean rollback(BusinessActionContext actionContext);
}
对服务 B 定义一个 TCC 接口:
public interface TccActionTwo {@TwoPhaseBusinessAction(name = "DubboTccActionTwo", commitMethod = "commit", rollbackMethod = "rollback", useTCCFence = true)public boolean prepare(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "b") String b);public boolean commit(BusinessActionContext actionContext);public boolean rollback(BusinessActionContext actionContext);
}
在业务系统中开启全局事务并执行服务 A 和服务 B 的 TCC 预留资源方法:
@GlobalTransactional
public String doTransactionCommit() {tccActionOne.prepare(null, "one");tccActionTwo.prepare(null, "two");
}
以上就是使用 Seata TCC 模式实现一个全局事务的例子。
使用 @GlobalTransactional 注解开启一个全局事务,而服务 A 和服务 B 的 TCC 接口为事务参与者,Seata 会把一个 TCC 接口当成一个 Resource,也叫做 TCC Resource。
TCC 接口可以是 RPC,也可以是 JVM 内部调用,这也意味着一个 TCC 接口,会有发起方和调用方两个身份。在以上例子中,TCC 接口在服务 A 和服务 B 中是发起方,在业务系统中是调用方。
Seata 启动时会对 TCC 接口进行扫描并解析,如果 TCC 接口是一个发起方,则在 Seata 启动时会向 TC 注册 TCC Resource,每个 TCC Resource 都有一个资源 id;如果 TCC 接口是一个调用方,则 Seata 会代理调用方,代理会拦截 TCC 接口的调用,即每次调用 Try 方法,会向 TC 注册一个分支事务,接着才执行原来的 RPC 调用。
当全局事务决议提交/回滚时,TC 会通过分支注册的资源 id 回调到对应参与者服务中执行 TCC Resource 的 Confirm/Cancel 方法。
原理
1.5.1版本之前

TM 开启全局事务时,RM 需要向 TC 发送注册信息,TC 保存分支事务的状态。TM 请求提交/回滚时,TC 需要向 RM 发送提交或者回滚信息。这样包含两个分支事务的分布式事务中,TC 与 RM 之间有四次 RPC。
1.5.1版本

TM 开启全局事务时,RM 不再需要向 TC 发送注册消息,而是把分支事务状态保存在了本地。TM 向 TC 发送提交或回滚消息后,RM 异步线程首先查出本地保存的未提交分支事务,然后向 TC 发送消息获取(本地分支事务)所在的全局事务状态,来决定是提交还是回滚本地事务。
这样优化后,RPC 次数减少了 50%,性能大幅提升。
处理异常
在 TCC 模型执行的过程中,可能会出现各种异常,最常见的有空回滚、幂等、悬挂等。
可以对 @TwoPhaseBusinessAction 注解的 useTCCFence 属性设置为 true,开启保护机制来解决这些问题。
并且需要在 MySQL 中创建 tcc_fence_log 表。
CREATE TABLE IF NOT EXISTS `tcc_fence_log`
(`xid` VARCHAR(128) NOT NULL COMMENT 'global id',`branch_id` BIGINT NOT NULL COMMENT 'branch id',`action_name` VARCHAR(64) NOT NULL COMMENT 'action name',`status` TINYINT NOT NULL COMMENT 'status(tried:1;committed:2;rollbacked:3;suspended:4)',`gmt_create` DATETIME(3) NOT NULL COMMENT 'create time',`gmt_modified` DATETIME(3) NOT NULL COMMENT 'update time',PRIMARY KEY (`xid`, `branch_id`),KEY `idx_gmt_modified` (`gmt_modified`),KEY `idx_status` (`status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
处理空回滚问题
空回滚指在一个分布式事务中,在没有调用参与者的 Try 方法的情况下,TM 驱动二阶段回滚调用了参与者的 Cancel 方法。
比如全局事务开启后,参与者 A 分支注册完成之后会执行参与者一阶段 RPC 方法,如果此时参与者所在的机器发生宕机,网络异常都会造成 RPC 调用失败,即参与者一阶段方法没有成功执行,但是此时全局事务已经开启,最终必须要走向结束状态,在全局事务回滚时会调用参与者的 Cancel 方法,从而造成空回滚。
如何解决空回滚问题?在一阶段执行 Try 方法时,往 tcc_fence_log 表里插入一条记录(包括事务的 XID 和 BranchID 信息),status 字段值为 TRIED。在二阶段执行 Cancel 方法时判断对应记录是否存在,如果不存在,则不执行回滚操作。
处理幂等问题
幂等问题指 TC 没有收到分支事务的响应,需要进行重试,因此 Confirm/Cancel 接口需要支持幂等处理,即不会产生资源重复提交或者释放。
比如参与者执行完二阶段操作之后,由于网络抖动或者宕机问题,会造成 TC 收不到参与者执行二阶段操作的返回结果,则 TC 会重复发起调用,直到成功收到二阶段操作的执行结果。
如何解决幂等问题?提交事务时首先会判断 tcc_fence_log 表中是否有对应的记录,如果没有则插入一条记录;如果有则判断事务状态,如果状态是 COMMITED,就不会再次提交。回滚事务的逻辑与之相似。
处理悬挂问题
悬挂问题指 二阶段 Cancel 方法比一阶段 Try 方法优先执行,由于允许空回滚的原因,执行完二阶段 Cancel 方法之后直接空回滚返回成功,此时全局事务已经结束,但是 Try 方法随后执行,就会造成一阶段 Try 方法预留的资源永远无法提交和释放了。
比如执行一阶段 Try 方法时,出现网络拥堵,由于 Seata 全局事务有超时限制,执行 Try 方法超时后,TM 决议全局回滚,回滚完成后如果此时 RPC 请求才到达参与者,然后参与者执行 Try 方法进行资源预留,从而造成悬挂。
如何解决悬挂问题?当执行二阶段 Cancel 方法时,先判断 tcc_fence_log 表是否存在当前 xid 的记录,如果不存在则插入一条记录,状态是 SUSPENDED,并且不执行回滚操作。后面执行 Try 方法时首先会向 tcc_fence_log 表插入一条当前 xid 的记录,这样会造成主键冲突,从而避免了悬挂问题。
相关文章:
Seata架构篇 - TCC模式
TCC 模式 概述 TCC 是分布式事务中的两阶段提交协议,它的全称为 Try-Confirm-Cancel,即资源预留(Try)、确认操作(Confirm)、取消操作(Cancel)。Try:对业务资源的检查并…...
前端最全面试题整理
前端基础 一、 HTTP/HTML/浏览器 1、说一下 http 和 https https 的 SSL 加密是在传输层实现的。 (1) http 和 https 的基本概念 http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(T…...
大数据之-Nifi-监控nifi数据流信息_监控数据来源_bub轻松复现---大数据之Nifi工作笔记0011
通过数据流功能可以轻松复现,数据的流向在某个时间点数据是怎么流动的,出现了什么问题,太强大了.. 真的是,可以看到通过右键,处理器,打开view data province就可以看到, 上面是处理器处理数据的详细信息 点击左侧的详情图标可以查看详情信息,details是这个事件处理的内容详情,…...
CUDA编程接口
编程接口 文章目录编程接口3.1利用NVCC编译3.1.1编译流程3.1.1.1 离线编译3.1.1.2 即时编译3.1.2 Binary 兼容性注意:仅桌面支持二进制兼容性。 Tegra 不支持它。 此外,不支持桌面和 Tegra 之间的二进制兼容性。3.1.3 PTX 兼容性3.1.4 应用程序兼容性3.1…...
惠普打印机使用
https://support.hp.com/cn-zh/product/hp-officejet-4500-all-in-one-printer-series-g510/3919445/document/c02076511HP 打印机 - 无法打印校准页本文适用于 HP 喷墨打印机。安装新墨盒后,打印机无法按预期打印校准页。步骤 1:确保打印机可以开始打印…...
Ubuntu升级cmake
目录 1、下载cmake安装包 2、开始安装 3、查看cmake版本 参考链接: https://blog.csdn.net/qq_27350133/article/details/121994229 1、下载cmake安装包 cmake安装包下载:download | cmake 我们根据自身需求下载所需版本的cmake安装包,这…...
CCNP350-401学习笔记(101-150题)
101、Refer to the exhibit SwitchC connects HR and Sales to the Core switch However, business needs require that no traffic from the Finance VLAN traverse this switch. Which command meets this requirement? A. SwitchC(config)#vtp pruning B. SwitchC(config)#…...
分享112个HTML娱乐休闲模板,总有一款适合您
分享112个HTML娱乐休闲模板,总有一款适合您 112个HTML娱乐休闲模板下载链接:https://pan.baidu.com/s/15uBy1SVSckPPMM55fiudeQ?pwdkqfz 提取码:kqfz Python采集代码下载链接:采集代码.zip - 蓝奏云 Bootstrap视频网站模板 …...
k8s快速入门
文章目录一、Kubernetes(K8S)简介1、概念1.1 Kubernetes (K8S) 是什么1.2 核心特性1.3 部署方案2、Kubernetes 集群架构2.1 架构2.2 重要概念 Pod2.3 Kubernetes 组件二、Kubernetes集群安装1、安装方式介绍2、minikubute安装3、裸机搭建(Bar…...
NG ZORRO知识点总结
NG ZORRO的常用属性,包括但不限于,结合代码 <button nz-button [nzType]"primary" [nzSize]"large" [nzLoading]"loading" [nzDisabled]"disabled" (click)"onClick()">点击我</button>nz-button是一个按钮组件…...
go中的值方法和指针方法
go中的值方法和指针方法1前言2 不同类型的对象调用不同类型的方法2.1 值对象可以调用值方法和指针方法3 指针对象可以调用值方法和指针方法4 !注意:结构体对象实现接口方法1前言 golang中在给结构体对象添加方法时,接收者参数类型可以有两种…...
OKR常见挑战以及应对方法探讨
背景 OKR是大家经常听到的一个词,也有不少团队说自己实行过,但每个实行过的团队都遇到过挑战。很多团队都感觉OKR有些空,很难落地,普通团队成员更是时常感觉无所适从,感觉就像看电影。2022年我们在更大的范围落地了OK…...
SpringAMQP消息队列(SpringBoot集成RabbitMQ)
一、初始配置1、导入maven坐标<!--rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>2、yml配置spring:rabbitmq:host: 你的rabbitmq的ipport: …...
DIDL5_数值稳定性和模型初始化
数值稳定性和模型初始化数值稳定性梯度不稳定的影响推导什么是梯度消失?什么是梯度爆炸?如何解决数值不稳定问题?——参数初始化参数初始化的几种方法默认初始化Xavier初始化小结当神经网络变得很深的时候,数值特别容易不稳定。我…...
火狐浏览器推拽开新的窗口
今天我测试的时候,发现我拖拽一下火狐会打开了新的窗口,谷歌就不会,所以我们要阻止一下默认行为const disableFirefoxDefaultDrop () > {const isFirefox navigator.userAgent.toLowerCase().indexOf(firefox) ! -1if (isFirefox) {docu…...
vrrp+mstp+osfp经典部署案例
LSW1和LSW2和LSW3和LSW4上面启用vrrpmstp组网: vlan 10 全走LSW1出再走AR2到外网,vlan 20 全走LSW2出再走AR3到外网 配置注意:mstp实例的根桥在哪,vrrp的主设备就是谁 ar2和ar3上开nat ar2和ar3可以考虑换成两台防火墙来做&…...
AI_News周刊:第二期
2023.02.13—2023.02.17 1.ChatGPT 登上TIME时代周刊封面 这一转变标志着自社交媒体以来最重要的技术突破。近几个月来,好奇、震惊的公众如饥似渴地采用了生成式人工智能工具,这要归功于诸如 ChatGPT 之类的程序,它对几乎任何查询做出连贯&a…...
【C++的OpenCV】第一课-opencv的间接和安装(Linux环境下)
第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意:官网为英文版本,可以使用浏览器自带的翻译插件进行翻译,真心不推荐大家去看别人翻译的&am…...
为什么建议使用你 LocalDateTime ,而不是 Date
为什么建议使用你 LocalDateTime ,而不是 Date? 在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗 通过阅读本篇文章你将了解到: 为什么需要LocalDate…...
【大数据】HADOOP-YARN容量调度器Spark作业实战
目录需求配置多队列的容量调度器验证队列资源需求 default 队列占总内存的40%,最大资源容量占总资源的60% ops 队列占总内存的60%,最大资源容量占总资源的80% 配置多队列的容量调度器 在yarn-site.xml里面配置使用容量调度器 <!-- 使用容量调度器…...
Unity Addressable系统面板配置避坑指南:从Profile到Content Update,新手必看的10个关键设置
Unity Addressable系统配置避坑实战:10个关键设置详解 Addressable系统作为Unity资源管理的重要工具,其配置面板的复杂性常常让开发者望而生畏。本文将聚焦实际项目中最容易出错的10个关键设置,从Profile到Content Update,逐一剖…...
科研绘图升级:用CMplot为你的基因组文章制作高颜值SNP密度图(R实战)
科研绘图升级:用CMplot为你的基因组文章制作高颜值SNP密度图(R实战) 在基因组学研究中,数据可视化不仅是结果展示的手段,更是科学叙事的重要语言。一张精心设计的SNP密度图,能够直观呈现全基因组范围内单核…...
命令行与IM桥接工具:适配器模式实现统一消息通知
1. 项目概述与核心价值最近在折腾一个挺有意思的东西,一个叫tmwgsicp/im-cli-bridge的项目。光看这个名字,可能有点摸不着头脑,我来拆解一下。tmwgsicp大概率是作者的用户名或者组织名,im-cli-bridge才是核心。im是即时通讯&#…...
告别天书:用Python+NumPy手把手实现Turbo码的迭代译码(附完整代码)
告别天书:用PythonNumPy手把手实现Turbo码的迭代译码(附完整代码) 在通信系统的演进历程中,Turbo码的出现犹如一场静默的革命。1993年,当Berrou等人首次公开这项技术时,其接近香农极限的性能让整个学术界为…...
ProxyClaw住宅代理实战:破解反爬虫,赋能AI智能体与数据工程
1. 项目概述:ProxyClaw,一个为AI与数据工程而生的住宅代理网络 如果你正在构建一个需要从互联网上大规模、稳定抓取数据的AI智能体、自动化机器人或者数据管道,那么“被目标网站封禁”这件事,大概率是你最头疼的日常。无论是电商平…...
终极KMS激活指南:如何一键永久激活Windows和Office
终极KMS激活指南:如何一键永久激活Windows和Office 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统弹出激活警告而烦恼吗?或者Office软件突然变成只读模…...
为智能硬件项目集成大模型能力利用Taotoken实现低成本高可用的方案
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为智能硬件项目集成大模型能力利用Taotoken实现低成本高可用的方案 在智能家居、物联网等嵌入式硬件项目中引入大模型能力…...
低成本传感器动态校准:SenDaL框架原理与应用
1. 低成本传感器校准的行业痛点与SenDaL解决方案在智能家居和工业物联网领域,我们经常面临一个尴尬的境地:高精度传感器价格昂贵难以大规模部署,而低成本传感器的数据质量又令人担忧。以PM2.5监测为例,专业级β射线传感器的价格可…...
基于Telegram的AI聊天机器人SirChatalot部署与多模态功能配置指南
1. 项目概述:打造你的专属AI骑士 如果你厌倦了那些功能单一、反应迟钝的聊天机器人,想拥有一个既能深度对话、又能看图说话、甚至能帮你搜索网页和生成图片的“全能型”AI伙伴,那么 SirChatalot 这个项目绝对值得你投入时间。它本质上是一个…...
Gemini3.1Pro透明化指南:模型卡与数据卡入口解析
在 2026 年,越来越多的团队开始把“模型怎么用”升级为“模型用得是否可控、可追溯”。尤其是涉及合规审计、数据治理与风险评估时,工程侧最需要的往往是:能快速找到模型信息与数据来源的透明化页面入口,确保链路清晰、记录完整、…...
