分布式事务:XA和Seata的XA模式

这篇具有很好参考价值的文章主要介绍了分布式事务:XA和Seata的XA模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上一篇内容《从2PC和容错共识算法讨论zookeeper中的Create请求》介绍了保证分布式事务提交的两阶段提交协议,而XA是针对两阶段提交提出的接口实现标准,本文则对XA进行介绍。

1. XA

XA (eXtended Architecture 扩展架构)X/Open组织提出的跨异构技术实现两阶段提交的接口标准。

分布式事务包含两种类型:数据库内部的分布式事务,在这种情况下,所有参与事务的节点都运行相同的数据库软件;异构分布式事务,参与者由两种或两种以上的不同数据库软件组成。

它于 1991 年推出并得到了广泛的实现:许多传统关系数据库包括 PostgreSQL、MySQL、DB2、SQL Server 和 Oracle;消息代理包括 ActiveMQ、HornetQ、MSMQ 和 IBM MQ都支持 XA。它不是一个网络协议而是定义了事务管理器(Transaction Manager)、应用程序(Application Program)资源管理器(Resource Manager)之间交互的CAPI(Common Application Programming Interface)接口标准,如下图所示,但是标准中并没有指明该如何实现,例如在Java EE中,XA使用的是Java事务API(JTA, Java Transaction API)实现的。

CAPI: 国际标准的通用应用交互接口。

其中三个组件的职责如下:

应用程序(Application Program):负责定义事务的开启、提交或中止,并能够访问事务内的资源(数据库等)

资源管理器(Resource Manager):负责对资源进行管理,相当于两阶段提交中的参与者,能够与事务管理器通过接口交互来传递必要的事务信息

事务管理器(Transaction Manager):负责管理全局事务,分配事务ID,监控事务的执行进度,并负责事务的开启、提交和回滚等,相当于两阶段提交中的协调者

XA同样也分为准备阶段提交阶段,它对分布式事务管理的流程如下

  • 准备阶段:AP与TM交互,开启一个全局分布式事务,并发送请求到每个RM,执行数据变更逻辑,此时每个RM会向TM发送请求注册分支事务,在执行完业务逻辑后报告准备提交的状态(事务执行完未提交),之后AP会根据RM的响应在提交阶段做出反馈

  • 提交阶段:如果所有的RM都回复“是”,表示它们已经准备好提交,那么AP会在该阶段向TM发出提交请求,分布式事务提交;否则,AP会向TM发出中止请求,分布式事务回滚

2. Seata的XA的模式

Seata中有三个角色事务管理器(Transaction Manager)资源管理器(Resource Manager)事务协调者(Transaction Coordinator)。在XA模式下,利用事务资源(数据库、消息服务等)对XA协议的支持,来对分布式事务进行管理。

但是,在Seata中三个角色的定义与XA协议标准中角色的定义有所区别:事务管理器(Transaction Manager)应该对应XA协议中的应用程序(Application Program);事务协调者(Transaction Coordinator)对应XA协议中的事务管理器(Transaction Manager)。我认为它们只是在命名上的区别,为了上下文各名词的统一,避免发生因名词不一致而理解混淆的问题,决定以XA标准协议中的定义进行讲解,特此强调

下图是Seata管理分布式事务的流程图,与第一小节中所述事务流程相同,不再赘述。

2.1 XA模式实战分析

有了理论基础,我们以商城系统为例进行简单地演示:订单、商品和购物车分别为三个微服务系统,在执行下单流程时会修改商品库存,生成订单和删除购物车中的商品,业务流程代码如下,注意其中包含事务异常回滚的代码

    @GlobalTransactional
    @Transactional(rollbackFor = Exception.class)
    public void saveOrder(OrderSaveParam orderSaveParam) {
        // 参数校验等必要操作
        // ...

        // 校验商品库存和上架状态
        checkGoodsStatusAndStock(goodsList, goodsCountMap);

        // 修改库存
        reduceGoodsCount(goodsCountMap);

        // 生成订单
        saveOrder(goodsList, goodsCountMap, orderSaveParam.getAddressId());

        // 删除购物车中商品
        shoppingCartService.deleteShoppingCartItem(orderSaveParam.getCartItemIds(), SecurityConstants.INNER);

        // 异常回滚事务
        int i = 1 / 0;
    }



分布式事务执行的准备阶段,流程图如下

  1. Order Server 在创建订单之前,会向 Seata Server(TM) 注册全局事务,并分配事务ID,对应的控制台日志如下

    2023-06-17 22:07:06.479  INFO 74703 --- [io-29009-exec-2] i.seata.tm.api.DefaultGlobalTransaction  : Begin new global transaction [127.0.0.1:8091:36427221250506976]
    
    
    
    
  2. Order Server REST调用 Goods Server 扣减商品数量,Goods Server 在执行数据修改逻辑前会向 Seata Server 注册分支事务,执行完业务逻辑后,并不执行事务提交

  3. Order Server REST调用 ShoppingCart Server 删除购物车中的商品,ShoppingCart Server 在执行数据修改逻辑前会向 Seata Server 注册分支事务,执行完业务逻辑后,同样不执行事务提交

  4. Order Server 本地执行生成订单和其他逻辑

接下来是分布式事务执行的提交阶段,因生成订单中代码逻辑抛出异常,所以该分布式事务会回滚,OrderServer中对应日志如下

2023-06-17 22:07:07.029  INFO 74703 --- [io-29009-exec-2] i.s.rm.datasource.xa.ConnectionProxyXA   : 127.0.0.1:8091:36427221250506976-36427221250506978 was rollbacked
2023-06-17 22:07:07.220  INFO 74703 --- [io-29009-exec-2] i.seata.tm.api.DefaultGlobalTransaction  : Suspending current transaction, xid = 127.0.0.1:8091:36427221250506976
2023-06-17 22:07:07.220  INFO 74703 --- [io-29009-exec-2] i.seata.tm.api.DefaultGlobalTransaction  : [127.0.0.1:8091:36427221250506976] rollback status: Rollbacked



  1. Order Server 向 Seata Server 发送中止请求,随后 Seata Server 向 Goods Server 和 ShoppingCart Server 发送事务回滚请求

  2. Goods Server 和 ShoppingCart Server 收到事务回滚请求后,将各自注册的分支事务回滚,最终全局分布式事务回滚,以保证数据的一致性。Goods Server 分支事务回滚对应的日志如下,可以发现分支事务的ID为全局事务ID-分支ID,并显示PhaseTwo_Rollbacked 在阶段二回滚

2023-06-17 22:07:07.081  INFO 74680 --- [h_RMROLE_1_4_24] i.s.c.r.p.c.RmBranchRollbackProcessor    : rm handle branch rollback process:xid=127.0.0.1:8091:36427221250506976,branchId=36427221250506986,branchType=XA,resourceId=jdbc:mysql://127.0.0.1:3306/fy_mall_goods,applicationData=null
2023-06-17 22:07:07.081  INFO 74680 --- [h_RMROLE_1_4_24] io.seata.rm.AbstractRMHandler            : Branch Rollbacking: 127.0.0.1:8091:36427221250506976 36427221250506986 jdbc:mysql://127.0.0.1:3306/fy_mall_goods
2023-06-17 22:07:07.096  INFO 74680 --- [h_RMROLE_1_4_24] i.s.rm.datasource.xa.ResourceManagerXA   : 127.0.0.1:8091:36427221250506976-36427221250506986 was rollbacked
2023-06-17 22:07:07.096  INFO 74680 --- [h_RMROLE_1_4_24] io.seata.rm.AbstractRMHandler            : Branch Rollbacked result: PhaseTwo_Rollbacked



注:如果有朋友想试试Seata的XA模式,可以参考示例代码仓库FangYuan33/book-spring-cloud,对应的方法入口为/saveOrder

3. 对XA的思考

XA能够保持多个参与者数据相互一致,但是同时也引入了比较严重的运维问题

因为如果协调者宕机,那么其中已经准备但未提交事务的所有参与者都会被阻塞。被阻塞的根本是,例如在读已提交隔离级别上,数据库事务通常会获取到待修改行数据的行级排他锁来防止脏写。在分布式事务提交或中止前,参与者数据库不能释放这些锁,因此协调者宕机多久,这些锁就要持有多久(在没有认为干预的情况下)。这些锁被持有的期间,导致其他事务不能修改这些数据(根据数据库的不同,读取操作也可能被阻塞),所以这些数据相关的业务都会被阻塞,导致应用大面积的不可用,直至存疑事务被解决(提交/中止)。

理论上,如果协调者崩溃并重新启动,它应该从日志中恢复事务的状态,并解决现存的疑虑事务,但是在实际生产中,仍然会有疑虑事务的出现(可能是事务日志被破坏)。也许你可能会考虑将相关应用的数据库服务器重启,但是在2PC正确的实现中,为了原子性的保证,重启后也必须持有存疑事务的锁。那么这样唯一的解决方案是让管理员手动提交还是回滚事务,这是引入运维问题的所在。不过,许多XA事务的实现都有一个叫做启发式决策的逃生出口,允许参与者单方面决定提交或放弃一个存疑事务,而无需等待协调者的决定,但是这也正是避免灾难性情况的手段,而不是为了日常的使用,因为这种方式有可能会破坏事务的原子性。

所以,协调者的高可用是需要我们考虑的问题,它本身也是一种数据库(保存了事务的结果),需要像其他应用数据库服务一样被认真的对待。


巨人的肩膀

  • 《数据密集型应用系统设计》:第九章 一致性与共识

  • 百度百科:XA

  • 分布式事务之XA方案(Seata实现)

  • 浅尝分布式事务

  • Seata官方文档

  • MySQL 中基于 XA 实现的分布式事务

  • 还不会分布式事务,seata xa模式入门实战送上

  • 原文收录:GitHub-Enthusiasm

作者:京东物流 王奕龙

来源:京东云开发者社区 自猿其说Tech 转载请注明来源文章来源地址https://www.toymoban.com/news/detail-710486.html

到了这里,关于分布式事务:XA和Seata的XA模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 分布式事务Seata实战-AT模式(注册中心为Eureka)

    大致记录Seata的AT模式下创建项目过程中需要注意的点和可能遇到的问题。 本项目是以官网的给的示例(即下图)进行创建的,以Eureka为注册中心。 官网:Seata AT 模式 | Apache Seata™ 官方代码示例:   快速启动 | Apache Seata™ 此文章涉及的项目代码链接:seata-at: 分布式事务解

    2024年01月19日
    浏览(34)
  • Java微服务分布式事务框架seata的TCC模式

    🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 专栏 描述 Java项目实战 介绍Java组件安装、使用;手写框架等 Aws服务器实战 Aws Linux服务器上操作nginx、git、JDK、Vue Jav

    2024年03月23日
    浏览(35)
  • 《微服务实战》 第三十章 分布式事务框架seata TCC模式

    第三十章 分布式事务框架seata TCC模式 第二十九章 分布式事务框架seata AT模式 本章节介绍分布式事务框架seata TCC模式,上一章节介绍seata以及集成到Springboot、微服务框架里。 一个分布式的全局事务,整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要

    2024年02月12日
    浏览(37)
  • springcloud3 分布式事务解决方案seata之AT模式5

    1.XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源; 2.XA模式依赖数据库机制实现回滚;AT模式利用数据库快照实现数据回滚 3.XA模式强一致;AT模式最终一致。 1.2 AT模式原理 一阶段: 1.TM发起并注册全局事务到TC; 2.TM调用分支事务; 3.RM进行注册分支

    2024年02月07日
    浏览(39)
  • 分布式:一文吃透分布式事务和seata事务

    什么是事务 事务是并发控制的单位,是用户定义的一个操作序列。 事务特性 原子性(Atomicity): 事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。 一致性(Consistency): 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性

    2024年02月07日
    浏览(48)
  • 【分布式事务】Seata 开源的分布式事务解决方案

    Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 阿里巴巴作为国内最早一批进行应用分布式(微服务化)改造的企业,很早就遇到微服务架构下

    2024年02月02日
    浏览(41)
  • Seata分布式事务

    本地事务,也就是传统的单机事务。在传统数据库事务中,必须要满足四个原则: 分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如: 跨数据源的分布式事务 跨服务的分布式事务 综合情况 完成上面的操作需要访问三个不同的微服务和三个不同的

    2024年02月09日
    浏览(34)
  • 分布式事务 Seata

    事务(Transaction)是计算机科学中的一个重要概念,主要是指一个 完整的、不可分割的操作序列 。在关系型数据库中,事务通常用于描述对数据库进行的一系列操作的执行单元。 事务的ACID特性 : 原子性(Atomicity):事务是一个原子操作,要么全部执行,要么全部回滚。如

    2024年02月17日
    浏览(37)
  • 分布式事务框架Seata

    分布式事务框架Seata 一、seata是什么 在微服务架构下,由于数据库和应用服务的拆分,导致原本一个事务单元中的多个 DML 操作,变成了跨进程或者跨数据库的多个事务单元的多个 DML 操作, 而传统的数据库事务无法解决这类的问题,所以就引出了分布式事务的概念。 分布式

    2024年02月10日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包