如何设计分布式系统-分布式事务-XA?
创始人
2024-03-04 19:03:30
0

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

       如何设计分布式系统-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

javax.transactionjta1.1

mysqlmysql-connector-java6.0.6
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();//创建事务分支的xidXid 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模型

相关内容

热门资讯

美国发布H-1B签证新规,优先... 当地时间12月23日,美国国土安全部发布新规,正式以“加权选择”机制取代H-1B签证原有的随机抽签制...
悉尼恐袭事件,意外替德国默茨政... 刚刚过去的一周,发生在澳大利亚的悉尼邦迪海滩恐怖袭击事件引起全球关注。 对于万里之外的德国而言,这场...
视频丨“粤车南下”驶入香港市区... 今天(12月23日),“粤车南下”驶入香港市区政策正式实施,符合条件的广东私家车可直接驶入香港市区,...
立白回应与经销商解约纠纷:个别... 12月23日,红星新闻报道《多地代理商称与立白集团解约后 对方未按约交接市场致严重损失,律师解读》一...
原创 宁... 据北京日报报道,12月中下旬的东亚地缘舞台格外热闹,日本首相高市早苗的一系列外交动作让外界看得眼花缭...
原创 阿... ATP针对大师赛和500赛事稳定参赛所设立的奖金,金额已可与大满贯奖金相媲美。目前的奖金榜显示,阿尔...
长春一女子打车遇“最炫出租车”... 极目新闻记者 王柳钦 近日,有网友发视频称,她和朋友在吉林长春乘坐出租车时,意外坐上了一辆改装有绚丽...
一次性信用修复政策落地,消金公... 一次性信用修复政策重磅落地,12月22日,中国人民银行发布一次性信用修复政策:明确对特定时期、特定金...
从“无”到“有”、从“有”到“... 浦东新区法律援助30周年暨《上海市法律援助若干规定》专题研讨会日前在浦东国际法律服务园举行。 本次研...
暴涨500%!19岁巴尔泰萨吉... 在意甲的舞台上,年轻球员的崛起往往令人瞩目,而19岁的巴尔泰萨吉正是近期最耀眼的新星之一。随着德转最...