当前位置: 首页 > news >正文

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 &#xff01;注意&#xff1a;结构体对象实现接口方法1前言 golang中在给结构体对象添加方法时&#xff0c;接收者参数类型可以有两种…...

OKR常见挑战以及应对方法探讨

背景 OKR是大家经常听到的一个词&#xff0c;也有不少团队说自己实行过&#xff0c;但每个实行过的团队都遇到过挑战。很多团队都感觉OKR有些空&#xff0c;很难落地&#xff0c;普通团队成员更是时常感觉无所适从&#xff0c;感觉就像看电影。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_数值稳定性和模型初始化

数值稳定性和模型初始化数值稳定性梯度不稳定的影响推导什么是梯度消失&#xff1f;什么是梯度爆炸&#xff1f;如何解决数值不稳定问题&#xff1f;——参数初始化参数初始化的几种方法默认初始化Xavier初始化小结当神经网络变得很深的时候&#xff0c;数值特别容易不稳定。我…...

火狐浏览器推拽开新的窗口

今天我测试的时候&#xff0c;发现我拖拽一下火狐会打开了新的窗口&#xff0c;谷歌就不会&#xff0c;所以我们要阻止一下默认行为const disableFirefoxDefaultDrop () > {const isFirefox navigator.userAgent.toLowerCase().indexOf(firefox) ! -1if (isFirefox) {docu…...

vrrp+mstp+osfp经典部署案例

LSW1和LSW2和LSW3和LSW4上面启用vrrpmstp组网&#xff1a; vlan 10 全走LSW1出再走AR2到外网&#xff0c;vlan 20 全走LSW2出再走AR3到外网 配置注意&#xff1a;mstp实例的根桥在哪&#xff0c;vrrp的主设备就是谁 ar2和ar3上开nat ar2和ar3可以考虑换成两台防火墙来做&…...

AI_News周刊:第二期

2023.02.13—2023.02.17 1.ChatGPT 登上TIME时代周刊封面 这一转变标志着自社交媒体以来最重要的技术突破。近几个月来&#xff0c;好奇、震惊的公众如饥似渴地采用了生成式人工智能工具&#xff0c;这要归功于诸如 ChatGPT 之类的程序&#xff0c;它对几乎任何查询做出连贯&a…...

【C++的OpenCV】第一课-opencv的间接和安装(Linux环境下)

第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意&#xff1a;官网为英文版本&#xff0c;可以使用浏览器自带的翻译插件进行翻译&#xff0c;真心不推荐大家去看别人翻译的&am…...

为什么建议使用你 LocalDateTime ,而不是 Date

为什么建议使用你 LocalDateTime &#xff0c;而不是 Date&#xff1f; 在项目开发过程中经常遇到时间处理&#xff0c;但是你真的用对了吗&#xff0c;理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗 通过阅读本篇文章你将了解到&#xff1a; 为什么需要LocalDate…...

【大数据】HADOOP-YARN容量调度器Spark作业实战

目录需求配置多队列的容量调度器验证队列资源需求 default 队列占总内存的40%&#xff0c;最大资源容量占总资源的60% ops 队列占总内存的60%&#xff0c;最大资源容量占总资源的80% 配置多队列的容量调度器 在yarn-site.xml里面配置使用容量调度器 <!-- 使用容量调度器…...

RedwoodJS数据备份与恢复终极指南:10个技巧保护你的应用数据安全 [特殊字符]

RedwoodJS数据备份与恢复终极指南&#xff1a;10个技巧保护你的应用数据安全 &#x1f512; 【免费下载链接】redwood RedwoodGraphQL 项目地址: https://gitcode.com/gh_mirrors/re/redwood RedwoodJS作为一款强大的全栈JavaScript框架&#xff0c;其数据安全保护机制对…...

03-从Chat到Act-Agent行动闭环的产品心理学拆解

从Chat到Act&#xff1a;Agent行动闭环的产品心理学拆解系列一&#xff1a;AI Agent GAP模型 | 第3篇&#xff08;深度型&#xff09; 从"一问一答"到"自主行动"&#xff0c;拆解Agent行动闭环背后的行为设计逻辑。本文你将获得 &#x1f504; Agent行动闭…...

2025_NIPS_Unveiling Induction Heads: Provable Training Dynamics and Feature Learning in Transformers

文章核心内容与创新点总结 核心内容 本文聚焦Transformer在n元马尔可夫链数据上的上下文学习(ICL)机制,通过分析含相对位置嵌入、多头softmax注意力和归一化前馈网络的双层Transformer训练动态,证明梯度流会收敛到实现“广义归纳头”(GIH)机制的极限模型。该模型中,第…...

如何自定义 LangGraph 的 State Schema 以支持复杂业务数据流

标题选项 《LangGraph实战进阶:自定义State Schema搞定复杂业务数据流全指南》 《从零搞定LangGraph复杂工作流:State Schema自定义从原理到落地》 《告别简单Demo:自定义LangGraph State Schema支撑企业级复杂数据流》 《LangGraph核心原理解锁:State Schema自定义设计思路…...

AI时代就业真相:小白程序员如何抓住大模型机遇,收藏这份必看指南!

智联招聘数据显示&#xff0c;AI短期内替代部分岗位&#xff0c;但新增岗位同样显著。编辑、翻译等白领岗位需求缩减&#xff0c;而AI工程师、数据标注师等需求激增。初级职位衰减&#xff0c;中级与高级职位增长&#xff0c;企业招聘更看重软技能与AI应用能力。建议关注新质生…...

网页项目之大五人格测试:认识真实的自己

大五人格测试&#xff1a;认识真实的自己 你是否曾好奇&#xff0c;自己的人格特质是什么&#xff1f;为什么有些人天生善于社交&#xff0c;有些人却更喜欢独处&#xff1f;为什么有人总是追求完美&#xff0c;有些人却随性自在&#xff1f; 心理学研究表明&#xff0c;人格的…...

Apache Weex内存泄漏终极解决方案:7个技巧让应用性能飙升

Apache Weex内存泄漏终极解决方案&#xff1a;7个技巧让应用性能飙升 【免费下载链接】incubator-weex Apache Weex (Incubating) 项目地址: https://gitcode.com/gh_mirrors/in/incubator-weex Apache Weex作为一款高性能的跨平台移动开发框架&#xff0c;在带来便捷开…...

Redux Thunk终极性能优化指南:从2秒到200毫秒的惊人提升

Redux Thunk终极性能优化指南&#xff1a;从2秒到200毫秒的惊人提升 【免费下载链接】redux-thunk Thunk middleware for Redux 项目地址: https://gitcode.com/gh_mirrors/re/redux-thunk Redux Thunk是Redux生态中最受欢迎和广泛使用的中间件&#xff0c;它为处理异步…...

ARM HCR_EL2寄存器解析与虚拟化控制

1. ARM HCR_EL2寄存器架构解析HCR_EL2&#xff08;Hypervisor Configuration Register&#xff09;是ARMv8/v9架构中用于控制虚拟化行为的关键系统寄存器。作为Hypervisor的主要控制接口&#xff0c;它定义了EL2对低特权级&#xff08;EL1/EL0&#xff09;执行环境的监控策略。…...

Nintendo Switch游戏安装终极指南:3种方法解决所有格式兼容问题

Nintendo Switch游戏安装终极指南&#xff1a;3种方法解决所有格式兼容问题 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer 还在为Nintendo Switch…...