【分布式事务-04】分布式事务seata的XA模式

news2024/11/28 16:39:12

redis系列整体栏目


内容链接地址
【一】分布式事务之2pc两阶段提交https://zhenghuisheng.blog.csdn.net/article/details/142406325
【二】分布式事务seata的安装下载与环境搭建https://zhenghuisheng.blog.csdn.net/article/details/142893117
【三】分布式事务seata的AT模式https://zhenghuisheng.blog.csdn.net/article/details/142977918
【四】分布式事务seata的XA模式https://zhenghuisheng.blog.csdn.net/article/details/143059012

分布式事务seata的XA模式

  • 一,分布式事务seata的XA模式
    • 1,XA模式的基本使用
    • 2,XA模式的底层实现
    • 3,XA模式源码实现
    • 4,XA总结

一,分布式事务seata的XA模式

在前面讲解了seata的安装以及核心的AT模式,AT模式相对来说比较主流,是阿里的首推模式,与之比较相像的模式就是本文的核心内容XA模式,本文主要是作为了解,因为XA模式能实现的,AT模式都能实现

XA模式的底层原理也比较简单,就是利用原生的spring事务做底层支持,通过对spring的事务封装来完成XA事务的支持,因此对于XA模式,不仅仅是支持关系型数据库,还得支持spring原生事务的支持

在了解XA模式的事务之前,可以直接查看官网:https://seata.apache.org/zh-cn/docs/dev/mode/xa-mode

1,XA模式的基本使用

在使用XA模式之前,需要启动nacos服务、TC服务,将这些服务成功启动

依旧是选用之前的三个服务,分别是订单服务,库存服务和账户服务,订单事务作为全局事务的发起者

在这里插入图片描述

在order订单服务配置seata的注册中心和配置中心配置如下,由于seata的默认mode模式为AT模式,因此如果想要使用XA模式的话,则需要手动的设置数据源的代理模式为XA模式

seata:
  #设置数据源的代理模式为XA,默认是AT
  data-source-proxy-mode: XA
  tx-service-group: default_tx_group
  registry:
    # 指定nacos作为注册中心
    type: nacos
    nacos:
      application: seata-server
      server-addr: localhost:8848
      group: SEATA_GROUP
  config:
    # 指定nacos作为配置中心
    type: nacos
    nacos:
      server-addr: localhost:8848
      namespace: 7e838c12-8554-4231-82d5-6d93573ddf32
      group: SEATA_GROUP
      data-id: seataServer.properties          

订单服务的代码如下,其内部实现和AT模式的代码一样,但是需要多加一个 Transactional 开启本地事务的注解

@Override
@Transactional
@GlobalTransactional(name="createOrder",rollbackFor=Exception.class)
public Order saveOrder(OrderVo orderVo) {
    //下单
    Order order = new Order();
    //创建订单 xxx
    Integer saveOrderRecord = orderMapper.insert(order);
    //扣减库存
    storageFeignService.deduct(orderVo.getCommodityCode(), orderVo.getCount());
    //扣减余额
    Boolean debit= accountFeignService.debit(orderVo.getUserId(), orderVo.getMoney());
    //更新订单
    Integer updateOrderRecord = orderMapper.updateOrderStatus(order.getId(),OrderStatus.SUCCESS.getValue());
    return order;
}

与AT模式不一致的是,XA模式不需要像AT模式一样需要通过前后置镜像结合undolog使用,因此在建表也不需要手动的建undolog日志表

2,XA模式的底层实现

xa模式的底层设计思想就是利用了2pc两阶段提交,先实现与提交操作,然后收集预提交的结果,根据全部的结果进行事务的提交或者回滚

//订单创建和更新库存预提交
int orderStatus = order.prepare();
int stockStatus = stock.prepare();
//判断二者之间的状态是否都为1
if(orderStatus && stockStatus){
    //同时提交
    order.commit();
    stock.commit();
}else{
    //同时回滚
    order.rollback();
    stock.rollback();
}

可以直接看官网给的架构流程图,在TM和RM之间定义了XA规范,通过RPC通信实现TM和RM之间的通信。在每一个RM中,先时开始XA和结束XA,然后执行XA的预提交操作,最后通过TC的反馈进行最终的提交或者回滚。在开启全局事务事务之后,也会注册一个全局的XID来保证事务的唯一性

通过下图的流程图可以知道,其具体的实现流程如下:

  • 首先是TM开启一个全局事务,然后与TC建立连接,TC返回一个xid给TM
  • 随后分支事务执行XA协议及预编译操作,分支事务直接使用spring的原生事务作为支持
  • 随后RM的本地事务会向TC注册一个本地分支,并携带TC的xid保证事务的一致性
  • 随后分支事务向TC上报预编译的状态,TC收集到全部状态之后再决定全局事务提交或者回滚
  • TC通过netty的方式向各个RM实现通信,只要有一个本地事务提交失败则全部失败回滚,只有全部成功才能通知全部的本地事务提交

在这里插入图片描述

在XA内部中,得直接使用spring原生的事务,内部可以直接使用 XADataSource 数据源,而不像AT模式一样,可以通过代理方式自定义数据源,但是AT模式需要手动的记录前置镜像和后置镜像以及undolog的日志,但是在XA模式中不需要,因此XA模式不仅仅要是关系型数据库,还得需要满足使用与原生的XA事务,即原生的spring事务

在这里插入图片描述

3,XA模式源码实现

首先可以直接查看XA的代理模式 PreparedStatementProxyXA 类,然后直接查看里面的执行更新的方法

public int executeUpdate() throws SQLException {
    return (Integer)ExecuteTemplateXA.execute(this.connectionProxyXA, (statement, args) -> {
        return statement.executeUpdate();
    }, this.getTargetStatement(), new Object[0]);
}

在这个execute执行方法时,方法内部主要有两个核心代码,一个是执行回滚的代码,另一个是执行提交的代码

res = statementCallback.execute(targetStatement, args);
connectionProxyXA.rollback();
connectionProxyXA.commit();

在提交事务中,用一个一把 synchronized 锁,也就是说RM的本地事务中,如果上一个事务没有提交或者回滚,那么下一个线程则会一直处于阻塞等待状态,在该方法内部中,当超时了则会直接抛出异常

public synchronized void commit() throws SQLException {
    if (!this.currentAutoCommitStatus) {
        if (this.xaActive && this.xaBranchXid != null) {
            try {
                this.end(67108864);
                long now = System.currentTimeMillis();
                this.checkTimeout(now);
                this.setPrepareTime(now);
                this.xaResource.prepare(this.xaBranchXid);
            } catch (XAException var8) {
               
            } finally {
                this.cleanXABranchContext();
            }
        }
    }
}

在提交事务中,主要是通过最下这段代码实现提交,需要携带本地事务的分支id

this.xaResource.prepare(this.xaBranchXid);

在回滚事务中的详细代码如下,需要通过携带全局事务XID和对应的本地事务的分支id

public void rollback() throws SQLException {
    if (!this.currentAutoCommitStatus) {
        if (this.xaActive && this.xaBranchXid != null) {
            try {
                if (!this.rollBacked) {
                    this.xaResource.end(this.xaBranchXid, 536870912);
                    this.xaRollback(this.xaBranchXid);
                }

                DefaultResourceManager.get().branchReport(BranchType.XA, this.xid, this.xaBranchXid.getBranchId(), BranchStatus.PhaseOne_Failed, (String)null);
            } finally {
                this.cleanXABranchContext();
            }

        }
    }
}

ResourceManagerXA 类中,内部定义了分支事务的提交回滚的详细细节

在这里插入图片描述

4,XA总结

xa模式的变成模型和At的模式编程模型一直,at模式通过快照结合undolog来实现一致性,xa模式通过定义xa规范来实现一致性,但是xa在提交时使用了jvm进程锁,效率不如at模式,因此在技术选型上,除非只能是用原生的xa规范,否则可以优先使用at模式实现分布式事务,因为xa模式能实现的,at模式都能实现,并且在效率方面,at模式的效率也是高于xa模式

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s ETCD数据备份与恢复

在 Kubernetes 集群中,etcd 是一个分布式键值存储,它保存着整个集群的状态,包括节点、Pod、ConfigMap、Secrets 等关键信息。因此,定期对 etcd 进行备份是非常重要的,特别是在集群发生故障或需要恢复数据的情况下。本文…

Axure科技感元件:打造可视化大屏设计的得力助手

Axure,作为一款专业的原型设计工具,凭借其强大的设计功能、丰富的组件库和灵活的交互能力,成为了许多设计师打造科技感设计的首选工具。其中,Axure科技感元件更是以其独特的魅力和实用性,在数据可视化大屏、登录界面、…

HarmonyOS开发(State模型)

一、State模型概述 FA(Feature Ability)模型:从API 7开始支持的模型,已经不再主推。 Stage模型:从API 9开始新增的模型,是目前主推且会长期演进的模型。在该模型中,由于提供了AbilityStage、Wi…

Leetcode—1114. 按序打印【简单】(多线程)

2024每日刷题&#xff08;179&#xff09; Leetcode—1114. 按序打印 C实现代码 class Foo { public:Foo() {firstMutex.lock();secondMutex.lock();}void first(function<void()> printFirst) {// printFirst() outputs "first". Do not change or remove t…

jupyter notebook远程连接服务器

jupyter notebook远程连接服务器 文章目录 jupyter notebook远程连接服务器jupyter是什么配置步骤安装jupyter生成jupyter配置文件编辑jupyter配置文件设置密码ssh隧道 启动顺序jupyter添加kernel下载ipykernel包添加kernel 测试遇到的问题 jupyter是什么 Jupyter Notebook是一…

fastStone Capture截图神器,你想要的功能它都有!

前言 大家好&#xff0c;我是小徐啊。从今天开始&#xff0c;小徐将介绍很多Java开发领域相关的软件工具资源&#xff0c;欢迎大家关注。今天&#xff0c;介绍一款非常小巧&#xff0c;但功能十分强大的图片软件&#xff0c;fastStone Capture。这款工具&#xff0c;主要是图片…

101、QT摄像头录制视频问题

视频和音频录制类QMediaRecorder QMediaRecorder 通过摄像头和音频输入设备进行录像。 注意: 使用Qt多媒体模块的摄像头相关类无法在Windows平台上进行视频录制&#xff0c;只能进行静态图片抓取但是在Linux平台上可以实现静态图片抓取和视频录制。 Qt多媒体模块的功能实现是依…

Git之代已修改文件的目录高亮设置

不管Android Studio或者Idea&#xff0c;进入Setting 选择如图所示&#xff0c;并进行勾选 就可以高亮了。

sentinel原理源码分析系列(四)-ContextEntry

启动和初始化完成后&#xff0c;调用者调用受保护资源&#xff0c;触发sentinel的机制&#xff0c;首先构建或获取Context和获取Entry&#xff0c;然后进入插槽链&#xff0c;决定调用是否通过&#xff0c;怎样通过 上图展示构建Context和获取Entry的类互动图 获取或构建Conte…

深度学习实战94-基于图卷积神经网络GCN模型的搭建以及在金融领域的场景

大家好,我是微学AI,今天给大家介绍一下深度学习实战94-基于图卷积神经网络GCN模型的搭建以及在金融领域的场景。文章首先介绍了GCN模型的原理及模型结构,随后提供了数据样例,并详细展示了实战代码。通过本文,读者可以深入了解GCN模型在金融场景下的应用,同时掌握代码的具…

keil5软件调试纪要

1&#xff0c;连接ST-LINK后查看连接信息。 2&#xff0c;除了printf调式外&#xff0c;keil5进行如下调式。 &#xff08;0&#xff09;进入调试界面 退出调式界面 &#xff08;1&#xff09; 打断点 &#xff08;2&#xff09;复位 &#xff08;3&#xff09;运行 &#xf…

判断一个数是不是素数(质数)(c语言)

素数的定义&#xff1a; 大于1的自然数&#xff0c;除了1和他本身不再有其它的因数 数学原理&#xff1a; 假设一个num不是素数&#xff0c;必然存在一个因子&#xff0c;该因为一定<√num&#xff0c;因此只要检测到√num中是否存在因子即可。 代码如下&#xff1a; #…

基于springboot+vue 大学毕业设计管理系统设计与实现

博主介绍&#xff1a;专注于Java vue .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的…

python 作业1

任务1: python为主的工作是很少的 学习的python的优势在于制作工具&#xff0c;制作合适的工具可以提高我们在工作中的工作效率的工具 提高我们的竞争优势。 任务2: 不换行 换行 任务3: 安装pycharm 进入相应网站Download PyCharm: The Python IDE for data science and we…

day02 -- docker

1.docker的介绍 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使…

androidStudio编译导致的同名.so文件冲突问题解决

files found with path lib/arm64-v8a/libserial_port.so from inputs: ...\build\intermediates\library_jni\debug\jni\arm64-v8a\libserial_port.so C:\Users\...\.gradle\caches\transforms-3\...\jni\arm64-v8a\XXX.so 解决方式如下&#xff1a; 1.将gradle缓存文件删…

mysql 10 单表访问方法

01.优化的过程 对于我们这些 MySQL 的使用者来说&#xff0c; MySQL 其实就是一个软件&#xff0c;平时用的最多的就是查询功能。DBA时不时丢过来一些慢查询语句让优化&#xff0c;我们如果连查询是怎么执行的都不清楚还优化个毛线&#xff0c;所以是时候掌握真正的技术了。我…

推荐?还是踩雷?3款中英互译软件大盘点,你真的选对了吗?

作为一个爱到处跑的人&#xff0c;我特别明白旅行的时候能说会道有多重要。不管是跟当地人聊天&#xff0c;还是看路标、菜单&#xff0c;有个好用的翻译软件是肯定少不了的。今天&#xff0c;我打算给你们介绍3款中英文互译的翻译工具&#xff0c;帮你挑出最适合自己的那一个。…

图论day62|拓扑排序理论基础、117.软件构建(卡码网)、最短路径之dijkstra理论基、47.参加科学大会(卡码网 第六期模拟笔试)

图论day62|拓扑排序理论基础、117.软件构建&#xff08;卡码网&#xff09;、最短路径之dijkstra理论基、47.参加科学大会&#xff08;卡码网 第六期模拟笔试&#xff09; 拓扑排序理论基础117.软件构建&#xff08;卡码网&#xff09;最短路径之dijkstra理论基础47.参加科学大…

大数据-173 Elasticsearch 索引操作 增删改查 详细 JSON 操作

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…