如何设计分布式系统-分布式事务-XA?

news2024/11/28 2:40:23

以下为个人观点,如有纰漏敬请指正。 

       如何设计分布式系统-CAP和BASE理论?_技术分子的博客-CSDN博客​​​​​​

     

         什么是事务?

       处理问题整个过程中同时具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),称为事务。

        什么分布式事务?

        分布式事务是涉及两个或多个网络主机的数据库事务。

        XA规范

        XA 是由 X/Open 组织提出的分布式事务规范,XA 规范主要定义了事务协调者(Transaction Manager)和资源管理器(Resource Manager)之间的接口。

        

        DTP(Distributed Transaction Processing) 模型图

       

  Xa主要规定了RM与TM之间的交互,下面来看下XA规范中定义的RM 和 TM交互的接口:

XA协议二阶段提交的一个流程示意图:

       MySQL 从5.0.3开始支持XA规范,且只有InnoDB存储引擎支持。

      

         

        MySQL支持XA规范后,分为内部XA事务、外部XA事务

       内部XA事务       

       MySQL整体架构分为三层: 网络连接层, 服务层, 存储引擎层。

       在向存储引擎提交数据时(存储引擎层),同时需要将提交的信息写入二进制日志(服务层),这就是一个分布式事务被称为内部XA事务。

        

       外部XA事务

       MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,可以提供跨库的分布式事务。当然也就成了外部XA事务的协调者角色。在crash recover时控制悬挂事务是全局commit,或者rollback。

java 使用 MySQL XA 外部事务 demo

<dependency>
   <groupId>javax.transaction</groupId>
   <artifactId>jta</artifactId>
   <version>1.1</version>
</dependency>

 <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>
public class XaDemo {

    public static MysqlXADataSource getDataSource(String connStr, String user, String pwd) {

        try {
            MysqlXADataSource ds = new MysqlXADataSource();
            ds.setUrl(connStr);
            ds.setUser(user);
            ds.setPassword(pwd);

            return ds;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static void main(String[] arg) {
        String connStr1 = "jdbc:mysql://192.168.0.1:3306/test";
        String connStr2 = "jdbc:mysql://192.168.0.2:3306/test";

        try {
            //从不同数据库获取数据库数据源
            MysqlXADataSource ds1 = getDataSource(connStr1, "root", "123456");
            MysqlXADataSource ds2 = getDataSource(connStr2, "root", "123456");

            //数据库1获取连接
            XAConnection xaConnection1 = ds1.getXAConnection();
            XAResource xaResource1 = xaConnection1.getXAResource();
            Connection connection1 = xaConnection1.getConnection();
            Statement statement1 = connection1.createStatement();
            
            //数据库2获取连接
            XAConnection xaConnection2 = ds2.getXAConnection();
            XAResource xaResource2 = xaConnection2.getXAResource();
            Connection connection2 = xaConnection2.getConnection();
            Statement statement2 = connection2.createStatement();

            //创建事务分支的xid
            Xid xid1 = new MysqlXid(new byte[] { 0x01 }, new byte[] { 0x02 }, 100);
            Xid xid2 = new MysqlXid(new byte[] { 0x011 }, new byte[] { 0x012 }, 100);

            try {
                //事务分支1关联分支事务sql语句
                xaResource1.start(xid1, XAResource.TMNOFLAGS);
                int update1Result = statement1.executeUpdate("update account_from set money=money - 50 where id=1");
                xaResource1.end(xid1, XAResource.TMSUCCESS);

                //事务分支2关联分支事务sql语句
                xaResource2.start(xid2, XAResource.TMNOFLAGS);
                int update2Result = statement2.executeUpdate("update account_to set money= money + 50 where id=1");
                xaResource2.end(xid2, XAResource.TMSUCCESS);
                
                // 两阶段提交协议第一阶段
                int ret1 = xaResource1.prepare(xid1);
                int ret2 = xaResource2.prepare(xid2);

                // 两阶段提交协议第二阶段
                if (XAResource.XA_OK == ret1 && XAResource.XA_OK == ret2) {
                    xaResource1.commit(xid1, false);
                    xaResource2.commit(xid2, false);

                    System.out.println("reslut1:" + update1Result + ", result2:" + update2Result);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

通过程序配合MySQL的XA事务功能,可能遇到的问题:

问题一、主备数据可以可能不一致性

        MySQL数据库的主备数据库的同步,通过Binlog的复制完成。而Binlog是MySQL数据库内部XA事务的协调者,并且MySQL数据库为binlog做了优化——binlog不写prepare日志,只写commit日志。

         所有的参与节点prepare完成,在进行xa commit前crash,crash recover如果选择commit此事务。

           由于binlog在prepare阶段未写,因此主库中看来,此分布式事务最终提交了,但是此事务的操作并未写到binlog中,因此也就未能成功复制到备库,从而导致主备库数据不一致的情况出现。

  在MySQL 5.5.16版本中做过测试,这个问题实际存在。crash recover之后,对xa recover返回的事务运行xa commit,对应事务提交,但是操作并未写入binlog,因此无法复制到备库。

        那么是否回滚所有prepare的事务,就可以避免此问题呢?结论是仍旧不行,不仅不能解决问题一,甚至可能引起问题二。

问题二:同一事务,在各参与节点,最终状态不一致(部分提交,部分回滚)。

   所有节点完成prepare,commit阶段部分已经提交 部分机器crash。crash recove 过程选择了 回滚。最终导致同一分布式事务,在各参与节点,最终状态不一致。

结论:

XA无法彻底解决分布式一致问题。

如何设计分布式系统-分布式事务-2PC、3PC?_技术分子的博客-CSDN博客

参考:

分布式事务

XA规范

XA模型

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

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

相关文章

Fucoidan-PLGA 岩藻多糖-聚乳酸-羟基乙酸共聚物 PLGA-PEG-Fucoidan

Fucoidan-PLGA 岩藻多糖-聚乳酸-羟基乙酸共聚物 PLGA-PEG-Fucoidan 中文名称&#xff1a;岩藻多糖-聚乳酸-羟基乙酸共聚物 英文名称&#xff1a;Fucoidan-PLGA 别称&#xff1a;PLGA修饰岩藻多糖&#xff0c;PLGA-岩藻多糖 岩藻多糖修饰的壳聚糖聚乳酸-羟基乙酸共聚物[poly…

软件测试面试技巧:如何提高面试通过率?这3点一定要做到

对于想要进入到软件测试岗的新手人员来说&#xff0c;面试这一关是非常重要的&#xff0c;它直接关系着你的去留&#xff0c;也关系后续的期待遇问题&#xff0c;那么&#xff0c;有没有什么技巧可以帮忙提高面试通过率呢&#xff1f; 关于这一问题答案&#xff0c;我从这几个方…

云计算模式的优势

PaaS是一种云计算形式&#xff0c;它提供了一个平台&#xff0c;允许开发人员和程序员开发、运行和管理自己的应用&#xff0c;而无需构建和维护相关的基础架构或平台。它就像是一个地基&#xff0c;由专门的平台服务提供商进行搭建和运营&#xff0c;并将该平台以服务的方式提…

D-022 SD/TF卡硬件电路设计

SD/TF卡硬件电路设计1 简介2 SD卡和Micro接口定义3 硬件设计要点4 硬件电路实战1 简介 SD卡按尺寸可以分为&#xff1a;标准SD卡、MiniSD卡、MicroSD卡。SD存储卡是一种基于半导体快闪记忆器的忆器设备。它具有体积小、传输速度快、支持热插拔等优点&#xff0c;在便携式装置领…

无延时直播/超低延时直播画面同步性测试(实测组图)

阿酷TONY / 原创 2022-11-30 / 长沙 / 超多组图 无延时直播/超低延时直播&#xff0c;主要只测试延时情况&#xff0c;没有涉及直播产品的功能、使用操作界面&#xff0c;有兴趣的朋友可以加联系我实际测试哦~~~ 1.无延时直播应用场景 无延时直播/超低延时常见应用场景&a…

用字典统计序列中键和值的数量collections.Counter()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 用字典统计序列中键和值的数量 collections.Counter() 选择题 以下python代码结果错误的一项是? from collections import Counter myList[a,b,a] print(【显示】myList,myList) myDictCoun…

全波形反演的深度学习方法: 第 3 章 常规反演

本章介绍反演的基础知识, 以及工程中的常规反演. 仅供内部培训. 3.1 地震数据采集 地震勘探中常使用人工激发的振动进行数据采集. 相应装置包括: 激发器是产生震动的装置, 如炸药, 地震车 (撞击地面). 在城市道路等具有车辆会产生振动的地方, 也可以不安装这类装置;地震检波…

定时执行专家 —— 定时循环发送UDP消息(例如:控制远程电脑的开机、关机、重启、打开和关闭程序等)

目录 ◆ 定时执行专家 - 发送UDP消息功能 - 设置方法 - 使用注意事项 ◆ 两种发送方式 ◆UDP消息的两种格式类型 ◆ 关于UDP协议 ◆ 定时执行专家 - 发送UDP消息功能 - 设置方法 &#xff08;1&#xff09;点击 “定时执行专家” 工具栏 “新建” 图标&#xff0c;打开…

低温烹饪过程中真空压力的自动控制

摘要&#xff1a;真空低温烹饪法作为已经经典的高品质烹饪方法&#xff0c;并未得到广泛的应用&#xff0c;主要问题是无法针对各种食材进行真空度的准确设定和控制。本文将针对低温烹饪目前存在的真空度控制问题&#xff0c;提出相应的解决方案。解决方案的核心是采用动态平衡…

Microolap DAC for MySQL驱动程序或其他库

Microolap DAC for MySQL驱动程序或其他库 用于MySQL和Delphi/CBuilder(也称为MySQLDAC)的Microolap直接访问组件是一组Borland Delphi/CBuilder组件&#xff0c;允许直接连接到MySQL数据库服务器。DAC for MySQL允许您创建Delphi/CBuilder应用程序&#xff0c;无需BDE、ODBC或…

连表查询数据,将数据分组串联到一起

场景&#xff1a;用户中心&#xff0c;一个用户是对应多个角色的&#xff0c;登录系统之后需要返回用户信息给前端&#xff0c;其中包含多个用户角色 这个时候&#xff0c;group_concat函数就出场了&#xff0c;当然这是针对于MySql去使用&#xff1b; group_concat函数首先根…

PX4代码解析(6)

一、前言 上一节介绍了PX4姿态估计调用函数的流程&#xff0c;这一节分享一下我对PX4姿态解算的解读.首先&#xff0c;要理解PX4姿态解算的程序&#xff0c;要先从传感器的特性入手&#xff0c;这里主要介绍的传感器有加速度计&#xff0c;磁力计&#xff0c;陀螺仪. 二、传感…

GeoServer服务迁移出现 EncryptionOperationNotPossibleException 错误的解决方案

目录1.前言2.GeoServer服务迁移一般流程3.遇到问题4.原因分析5.解决办法6.根本原因分析7.总结1.前言 这几天我在迁移 GeoServer 服务的时候发现&#xff0c;报了一个错&#xff0c;EncryptionOperationNotPossibleException &#xff0c;这个错误的大概意思是加密操作不可用异常…

Jenkins - 打造强大的前端自动化工作流

什么是 Jenkins&#xff1f; Jenkins 是一款业界流行的开源持续集成工具&#xff0c;广泛用于项目开发&#xff0c;具有自动化构建、测试和部署等功能。我们可以利用 Jenkins 来对项目的持续性集成进行管控处理。 Jenkins 任务的创建 这里就简单不再累赘说明 Jenkins 的安装启动…

CF思维训练,2020长春CCPC(A,D)

D. Knowledge Cards(华容道GAME) 题意&#xff1a;给定n*m的矩阵&#xff0c;初始在左上角有一摞牌&#xff0c;从上到下每张的数字构成了一个长度为k的排列&#xff0c;请问在保证1.不能使得牌在移动过程中重叠2.不能让牌反复出现在左上和右下角。这两个条件下&#xff0c;能…

是不是Jenkins大神,看这几个技巧就够

01 Performance插件兼容性问题 自由风格项目中&#xff0c;有使用 Performance 插件收集构建产物&#xff0c;但是截至到目前最新版本&#xff08;Jenkins v2.298&#xff0c;Performance&#xff1a;v3.19&#xff09;&#xff0c;此插件和Jenkins都存在有兼容性问题&#xf…

运筹说 第75期 | 数学家欧拉也玩跨界

莱昂哈德欧拉&#xff08;Leonhard Euler&#xff09;的一生&#xff0c;是为数学发展而奋斗的一生&#xff0c;他不但为数学界作出贡献&#xff0c;更把整个数学推至物理的领域。欧拉杰出的智慧&#xff0c;顽强的毅力&#xff0c;孜孜不倦的奋斗精神和高尚的科学道德&#xf…

用uniapp开发打包多端应用完整指南

一、uni-app项目介绍 用uni-app开发多端项目&#xff0c;一套代码可同时打包出各端小程序、h5和app&#xff0c;uni-app支持通过 HBuilderX可视化界面 和 vue-cli命令行 两种方式创建项目&#xff0c;下面示例项目采用 HBuilderX可视化界面 的方式创建&#xff0c;cli项目可参…

opencv c++ 图像梯度、边缘、锐化

图像梯度的目的&#xff1a; 获取图像上沿着某一方向或多个方向上&#xff0c;像素值的突变图像。 即&#xff1a; 对满足之间相互独立的函数&#xff0c; 求&#xff0c; 1、预备知识 1.1、常见的梯度计算算子 1.2、梯度计算方法 L2法&#xff1a; L1法&#xff1a; 1.3…

Packet Tracer - 比较 2960 和 3560

目标 第 1 部分&#xff1a;比较第 2 层和第 3 层交换机 第 2 部分&#xff1a;比较第 3 层交换机和路由器 拓扑图 背景信息 在本练习中&#xff0c;您将使用各种命令检查三种不同的交换拓扑&#xff0c;并且比较 2960 和 3560 交换机之间的异同。 您还将比较 1941 路由器和…