Seata流程源码梳理下篇-TC

我们上篇简单梳理了下TM、RM的一些流程(离现在过得挺久的了,这篇我们这篇来梳理下TC的内容。

TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

一、TC的定义

TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚

​ 这个是官网给出的定义,就是说其实全局事务的协调。具体来说例如:当某个TM(事务管理器)需要开启事务的时候,就需要一个协调者来驱动全局事务或提交,或回滚,这个概念我们开始的时候很容易与TM混淆。我们看到这两个一个是开始,一个是驱动,具体通过demo来说。

1、一些基本逻辑信息

用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:

  • 仓储服务(Storage):对给定的商品扣除仓储数量。
  • 订单服务(Order):根据采购需求创建订单。
  • 帐户服务(Account):从用户帐户中扣除余额。
  • 业务服务(Business):发起整个业务逻辑。

在这里插入图片描述
在这里插入图片描述

这个官网给出的例子,就是Business服务发起本次业务逻辑,也就是通过@GlobalTransactional来开始全局事务,然后后面的也就是TM的一些逻辑处理,这个我们上篇有说过,就是去调TC表示自己要开始全局事务,然后TC就会生成全局事务的XID,之后其调其他的分支事务Stock、Order的话就带上这个全局事务XID。然后这里TC就是一个协调者的角色,其他的TM、RM都想TC注册。例如如果后面如果@GlobalTransactional方法正常执行的话,就事务提交,其就向TC发送消息,然后TC去协调分支事务的提交。

​ 下面我们就来具体看下在TC中这些注册、提交、回滚等的操作。

二、TC的一些逻辑处理

1、前置内容

​ 首先在TC这边,关于对应请求的处理,入口都是RemotingProcessor接口的具体实现

在这里插入图片描述

​ 其的子类:

在这里插入图片描述

2、RM通道注册

​ RM(资源管理器)注册。我们上面有介绍过,Seata会代理服务关于数据库的操作。然后其数据源初始化的时候,就会向TC注册。

在这里插入图片描述

但我们需要注意,这个目前还只是channel的通道连接,不是具体的RM资源注册,具体的RM事务资源注册是在全局事务开始然后操作数据库的时候。

​ 对应到TC这边就是RegRmProcessor在处理,这个主要是保存Channel通道,与Netty相关的内容,目前还没具体研究,但影响不大。先不深入这个。

在这里插入图片描述

3、TM通道注册

在这里插入图片描述

​ 这个与前面的RM是类似的。

4、ServerOnRequestProcessor

​ 然后这个是一个核心的处理类,其用来处理各种类型的信息。

在这里插入图片描述

​ 我们可以看到,像分支注册、全局事务的开始、回滚都是这个Process处理的。

public class ServerOnRequestProcessor implements RemotingProcessor {private static final Logger LOGGER = LoggerFactory.getLogger(ServerOnRequestProcessor.class);private RemotingServer remotingServer;private TransactionMessageHandler transactionMessageHandler;public ServerOnRequestProcessor(RemotingServer remotingServer, TransactionMessageHandler transactionMessageHandler) {this.remotingServer = remotingServer;this.transactionMessageHandler = transactionMessageHandler;}@Overridepublic void process(ChannelHandlerContext ctx, RpcMessage rpcMessage) throws Exception {if (ChannelManager.isRegistered(ctx.channel())) {onRequestMessage(ctx, rpcMessage);} else {........if (LOGGER.isInfoEnabled()) {LOGGER.info(String.format("close a unhandled connection! [%s]", ctx.channel().toString()));}}}private void onRequestMessage(ChannelHandlerContext ctx, RpcMessage rpcMessage) {Object message = rpcMessage.getBody();RpcContext rpcContext = ChannelManager.getContextFromIdentified(ctx.channel());...........if (message instanceof MergedWarpMessage) {AbstractResultMessage[] results = new AbstractResultMessage[((MergedWarpMessage) message).msgs.size()];for (int i = 0; i < results.length; i++) {final AbstractMessage subMessage = ((MergedWarpMessage) message).msgs.get(i);results[i] = transactionMessageHandler.onRequest(subMessage, rpcContext);}MergeResultMessage resultMessage = new MergeResultMessage();resultMessage.setMsgs(results);remotingServer.sendAsyncResponse(rpcMessage, ctx.channel(), resultMessage);} else {// the single send request messagefinal AbstractMessage msg = (AbstractMessage) message;AbstractResultMessage result = transactionMessageHandler.onRequest(msg, rpcContext);remotingServer.sendAsyncResponse(rpcMessage, ctx.channel(), result);}}}

​ 然后处理的核心就是DefaultCoordinator,上面的AbstractRMHandler是RM的处理

在这里插入图片描述

5、DefaultCoordinator

​ 这里的主要用来处理TC的逻辑就是TCInboundHandler接口:

在这里插入图片描述

​ 通过这些Request我们也能找到其主要是用来处理全局事务的开启、分支事务的注册、全局事务的提交、回滚、状态这些。下面我们就来主要看下看下GlobalBeginRequestBranchRegisterRequestGlobalCommitRequest的处理。

1、GlobalBeginRequest的处理

在这里插入图片描述

在这里插入图片描述

​ 通过这里我们可以找到,在GlobalBegin开启全局事务的主要处理就是生成全局事务Xid返回。

在这里插入图片描述

public static GlobalSession createGlobalSession(String applicationId, String txServiceGroup, String txName,int timeout) {GlobalSession session = new GlobalSession(applicationId, txServiceGroup, txName, timeout);return session;
}
    public GlobalSession(String applicationId, String transactionServiceGroup, String transactionName, int timeout) {this.transactionId = UUIDGenerator.generateUUID();this.status = GlobalStatus.Begin;this.applicationId = applicationId;this.transactionServiceGroup = transactionServiceGroup;this.transactionName = transactionName;this.timeout = timeout;this.xid = XID.generateXID(transactionId);}

这里是全局事务的session,然后再通过session.begin来进行对应处理,例如将全局事务session保存到数据库:

在这里插入图片描述

在这里插入图片描述

​ 我们可以看到这里有多种处理方式、例如保存到文件、redis这些。目前我们是保存到数据库中,处理的就是DataBaseSessionManager

public class DataBaseSessionManager extends AbstractSessionManagerimplements Initialize {............@Overridepublic void addGlobalSession(GlobalSession session) throws TransactionException {if (StringUtils.isBlank(taskName)) {boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_ADD, session);if (!ret) {throw new StoreException("addGlobalSession failed.");}} else {boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);if (!ret) {throw new StoreException("addGlobalSession failed.");}}}

​ 这里之后就是DataBaseTransactionStoreManager处理入库逻辑

在这里插入图片描述

在这里插入图片描述

2、BranchRegisterRequest分支事务注册的处理

​ 再之后我们来看下分支事务的注册处理逻辑。分支事务的注册就是每个RM对应开始操作DB的时候(这个RM相关的内容上篇有提到过),向TC发起分支事务注册,代码逻辑就是放在seata代理的jdbc的ConnectionProxy

在这里插入图片描述

在这里插入图片描述

然后TC这边就会处理这个请求,可以看到这里就是生成并返回分支事务ID

在这里插入图片描述

在这里插入图片描述

同时会将当前分支事务保存到数据库中

在这里插入图片描述

3、GlobalCommitRequest全局事务提交的处理

​ 我们上篇有提到,再TM发起全局事务后,如果各个分支都执行成功后,其会向TC发起全局事务的提交。

对于我们官方给到的demo。我们看下关于事务相关的表的数据。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
然后各个分支都执行完成后,由TM来提交全局事务

在这里插入图片描述

在这里插入图片描述

​ 在TM提交后,我们来看下TC的处理:

在这里插入图片描述

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=F%3A%5CMarkDown-File%5C%E7%9F%A5%E8%AF%86%E7%82%B9%E8%B5%84%E6%96%99%5CSeata%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-TC.assets%5C在这里插入图片描述
&pos_id=img-hmn2nU2b-1695536657221)

​ 这里我们主要需要注意SessionHelper.forEach(globalSession.getSortedBranches(), branchSession对于每个branchSession的循环调用,也就是每个分支事务的session,在这里就会循环,然后调用每个分支进行分支事务的本地提交,也就是RM本地提交的处理。

在这里插入图片描述

然后RM的处理主要就是RMHandlerAT这个类在处理,因为我们当前是AT模式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

然后ResourceManager就是DataSourceManager

在这里插入图片描述

​ 这里主要是添加到异步队列中。

在这里插入图片描述

然后主要处理就是删除数据库的undo记录,就我们全局事务成功了,不需要使用undo来回滚本地事务了。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/140214.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ Primer 第5章 语句

C Primer 第5章 语句 5.1 简单语句一、空语句二、别漏写分号&#xff0c;也别多写分号三、复合语句&#xff08;块&#xff09; 5.2 语句作用域5.3 条件语句5.3.1 if语句一、使用if else语句二、嵌套if语句三、注意使用花括号四、悬垂else五、使用花括号控制执行路径 5.3.2 swi…

Oracle分区的使用详解:创建、修改和删除分区,处理分区已满或不存在的插入数据,以及分区历史数据与近期数据的操作指南

一、前言 什么是表分区: Oracle的分区是一种将表或索引数据分割为更小、更易管理的部分的技术。它可以提高查询性能、简化维护操作,并提供更好的数据组织和管理。 表分区和表空间的区别和联系: 在Oracle数据库中,表空间(Tablespace)是用于存储表、索引和其他数据库对…

Baichuan2 技术报告笔记

文章目录 预训练预训练数据模型架构TokenizerPositional EmbeddingsAcitivations and NormalizationsOptimizations 对齐Supervised Fine-TuningRLHF 安全性预训练阶段对齐阶段 参考资料 对Baichuan2技术报告阅读后的笔记 Baichuan2 与其他大模型的对比如下表 预训练 预训练数…

【Java开发】Redis位图实现统计日活周活月活

最近研究了使用 Redis 的位图功能统计日活周活等数据&#xff0c;特来和大家分享下&#xff0c;Redis 位图还可用于记录用户签到情况、判断某个元素是否存在于集合中等。 1 Redis 位图介绍 Redis 位图是一种特殊的数据结构&#xff0c;它由一系列位组成&#xff0c;每个位只能…

洛谷P8815:逻辑表达式 ← CSP-J 2022 复赛第3题

【题目来源】https://www.luogu.com.cn/problem/P8815https://www.acwing.com/problem/content/4733/【题目描述】 逻辑表达式是计算机科学中的重要概念和工具&#xff0c;包含逻辑值、逻辑运算、逻辑运算优先级等内容。 在一个逻辑表达式中&#xff0c;元素的值只有两种可能&a…

Appilot发布:打造面向DevOps场景的开源AI助手

今日&#xff0c;数澈软件Seal &#xff08;以下简称“Seal”&#xff09;宣布推出面向 DevOps 场景的 AI 助手 Appilot&#xff0c;这款产品将充分利用 AI 大语言模型的能力为用户提供变革性的部署和应用管理体验。Seal 此次发布的 Appilot 项目&#xff0c;可以让用户直接输入…

leetcode 22. 括号生成

2023.9.24 看到组合两个字&#xff0c;想到了回溯。 大致思路是将所有可能的组合列出来&#xff0c;通过中止条件筛选掉无效的括号。 第一个中止条件&#xff1a;如果右括号数量大于左括号&#xff0c;那括号肯定无效。 第二个中止条件&#xff1a;当左右括号数量相等&#x…

古代有没有电子元器件?

手机&#xff0c;电脑&#xff0c;电视等等电子产品&#xff0c;无时无刻充斥在我们的生活中&#xff0c;如果有一天突然没有了这些功能多样的电子产品&#xff0c;估计大部分人都会一时之间难以适应。 这就好比正在上网&#xff0c;结果突然被人断了网&#xff0c;导致无网络连…

Go语言入门篇

目录 一、基础数据类型 1.1 变量的定义方式 1.2 用%T输出变量的类型 二、复合数据类型 2.1 数组 2.1.2、数组的遍历 2.1.3 数组传参 2.2. 切片slice 2.2.1. 初始化切片 2.2.2. append向切片中追加元素 2.2.3. 切片的截取 2.3. map 2.3.1. map初始化 2.3.2. 添加和…

操作系统权限提升(三十)之数据库提权-SQL Server sp_oacreate+sp_oamethod(dba权限)提权

SQL Server sp_oacreate+sp_oamethod(dba权限)提权 sp_oacreate+sp_oamethod介绍 在xp_cmdshell被删除或不能利用是可以考虑利用sp_oacreate,利用前提需要sqlserver sysadmin账户服务器权限为system(sqlserver2019默认被降权为mssql)。sp_oacreate 是一个存储过程,可以…

【无标题】mysql 普通用户连接报错: MySql server has gone away

1、mysql 普通用户连接报错&#xff1a; MySql server has gone away 2、进入mysql错误日志位置查看输出日志显示错误为&#xff1a; [Warning] [MY-013130] [Server] Aborted connection 47 to db: unconnected user: tjcx host: 10.195.11.4 (init_connect command failed; …

基于docker进行Grafana + prometheus实现服务监听

基于docker进行Grafana Prometheus实现服务监听 Grafana安装Prometheus安装Jvm监控配置服务器主机监控(基础cpu&#xff0c;内存&#xff0c;磁盘&#xff0c;网络) Grafana安装 docker pull grafana/grafanamkdir /server/grafanachmod 777 /server/grafanadocker run -d -p…

汽车OTA

汽车OTA&#xff08;Over-The-Air&#xff09;技术是指通过无线网络对汽车进行软件升级、数据传输和远程诊断等功能的技术。随着汽车行业的数字化和智能化发展&#xff0c;OTA技术在汽车领域的应用越来越广泛&#xff0c;对于提高汽车性能、降低维修成本和提升用户体验具有重要…

Linux(ubuntu)系统更新后不能进入图形界面

最近需要跑一个深度学习的程序&#xff0c;把许久没用的ubuntu系统调了出来&#xff0c;手欠的我更新了一下系统&#xff0c;结果再启动&#xff0c;系统就只停留在光标闪动那里&#xff0c;不能看到图形界面了。网上查了一下&#xff0c;说是因为更新后&#xff0c;显卡驱动没…

Scrapy+Selenium自动化获取个人CSDN文章质量分

前言 本文将介绍如何使用Scrapy和Selenium这两个强大的Python工具来自动获取个人CSDN文章的质量分数。我们将详细讨论Scrapy爬虫框架的使用&#xff0c;以及如何结合Selenium浏览器自动化工具来实现这一目标。无需手动浏览每篇文章&#xff0c;我们可以轻松地获取并记录文章的…

MySQL常见join关联查询分析

1、join关联查询七大类型结构图 2、建表语句 CREATE TABLE t_dept (id INT(11) NOT NULL AUTO_INCREMENT,deptName VARCHAR(30) DEFAULT NULL,address VARCHAR(40) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;CREATE TABLE t_emp (id…

Go 并发可视化解释 - sync.Mute

在学习 Go 编程语言时&#xff0c;您可能会遇到这句著名的格言&#xff1a;“不要通过共享内存来进行通信&#xff1b;相反&#xff0c;通过通信来共享内存。” 这句话构成了 Go 强大并发模型的基础&#xff0c;其中通道&#xff08;channels&#xff09;作为协程之间的主要通信…

搭建安信可小安派Windows 开发环境

搭建小安派Windows 开发环境 Ai-Pi-Eyes 系列是安信可开源团队专门为Ai-M61-32S设计的开发板&#xff0c;支持WiFi6、BLE5.3。所搭载的Ai-M61-32S 模组具有丰富的外设接口&#xff0c;具体包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太网 (EMAC)、SD/MMC(SDH)、SP…

操作系统真象还原_访问vaddr对应的pte

须知&#xff1a; 只要开启了分页机制&#xff0c;不管物理地址还是虚拟地址在CPU面前都按照分页处理&#xff0c;也就是即便给出物理地址CPU也按虚拟地址对待。 为什么没有出现页目录表结构体&#xff0c;也没有页目录项结构体。页目录表在某一块内存中&#xff0c;页表也在某…

存储管理详解

目录 存储管理&#xff08;1&#xff09; 第一节 存储管理概述&#xff08;内存管理&#xff09; 一、存储体系 二、存储管理的任务 三、地址转换 存储管理&#xff08;2&#xff09; 第二节 分区管理方案 一、固定分区 二、可变分区 三、分区管理方案的优缺点 第…