事务连接中断_DBLE XA事务源码分析

4f440a4f7bb0e93a50042aab823f2d4a.png

原创: 高鹏

作者简介
高鹏,github主页[ https:// github.com/tankilo ]
15年本科毕业,github平常心提ISSUE和PR,投稿希望能结交志同道合的朋友。

本文目录:一、XA 本身
(一)拓扑结构
(二)MySQL XA SQL语法
(三)XA事务状态变迁图
(四)关注xa prepare
(五)binlog二、DBLE XA实现分析
(一)分库分表中间件用XA事务 解决跨库事务的思路
业务侧连接到中间件执行本地事务的一般步骤
分库分表中间件接受到用户本地事务命令的反应
(二)源码结构
transaction.xa
xa.TxState
xa.recovery
(三)客户端连接DBLE Server代码示例
(四)详细执行流程
显式事务 commit成功
显式事务 rollback成功
代码分析流程
(五)理解全局事务状态和分支事务状态的关系
(六)不按套路出牌的用户如何处理
(七)显式XA事务 部分场景下的commit失败时会自动回滚
(八)事务执行过程中,前端连接被关闭三、事务日志和事务恢复
(一)事务日志
刷盘时机
(二)事务恢复四、总结五、参考文章

一、XA 本身

关于xa本身不会过多介绍(因为我也是看别人写的啊),可以两个方向去搜索 1.【官方】xa规范官方文档和MySQL xa官方文档 2.【民间】别人已经学习过记录的博客
推荐阅读:https://www.jianshu.com/p/7003d58ea182(一)拓扑结构

f91695dbf8a137c5c12eddfd66b462aa.png

图片来源:https://www.jianshu.com/p/7003d58ea182

在DBLE这样的分库分表中间里,拓扑结构其实是这样的。

13b1c4b5188f0f026a28d459144c1f40.png


DBLE Server进程是AP,TM是作为代码逻辑模块内嵌在DBLE Server进程内部的。DBLE Server使用MySQL xa事务sql语法去定义事务边界。RM是分库分表背后的MySQL。(二)MySQL XA SQL语法
来源:https://dev.mysql.com/doc/refman/5.7/en/xa-statements.html

XA {START|BEGIN} xid [JOIN|RESUME]
XA END xid [SUSPEND [FOR MIGRATE]]
XA PREPARE xid
XA COMMIT xid [ONE PHASE]
XA ROLLBACK xid
XA RECOVER [CONVERT XID]
  • XA START和XA END用于确定一个分支事务的边界
  • XA PREPARE 和XA COMMIT,XA ROLLBACK用来做2PC
  • XA RECOVER是管控命令,用来查看一阶段prepare过但是还没二阶段commit或者rollback的分支事务

(三)XA事务状态变迁图
借用XA事务状态变迁来源:https://www.jianshu.com/p/7003d58ea182

0ab6251beca545118ec368490154d075.png

这个图需要注意的地方是:
(1)如果你xa start开启一个全局事务以后,你不走到两个终点,你是没法继续开启下一个xa事务的。即使你xa start后什么DML也没执行,你也需要按照xa end, xa rollback的流程这样结束事务,否则 XAER_RMFAIL: The command cannot be executed when global transaction is in the %s state 这样的报错就会来敲门。
(2)当分布式事务里只有一个RM,即分布式事务退化成本地事务了,xa commit one phase 时会将prepare和commit 一起完成。DBLE里面并没有使用这种优化!这样只有四种到最终状态的路径。

a2c08a1c5d2813957104d3c0fd9fb496.png


图片来源:https://www.jianshu.com/p/7003d58ea182(四)关注xa prepare
在xa prepare执行成功之前,如果你关闭到MySQL的链接,事务会被MySQL自动回滚的,不会留下任何副作用。
但是在xa prepare执行成功之后,你必须决定commit还是rollback,并且按照上图的流程图走到结束状态。因为xa prepare执行成功之后,事务信息将被持久化,不管连接断开还是MySQL Server重启,事务都将被重新恢复(通过informationschema.innodbtrx你可以查询到),这些事务占有的锁都会阻止其他会产生锁冲突的事务继续执行。这是和MySQL本地事务不同的地方。通过xa recover可以查询到这些xa prepare过的事务。

f7d60390d65c30faace548a546275f2b.png


图片来源:dble官方文档(五)binlog
binlog会记录xa事务的日志

5f4c84adc03fb24729b224e0dfda98bc.png

个人发现
1. 只有xa prepare执行后才会记录binlog,但是会记录到此为止的所有语句。
2. 没实际修改到数据的DML不会记录binlog二、DBLE XA实现分析

推荐阅读:https://actiontech.github.io/dble-docs-cn/2.Function/2.05distributetransaction.html
可以先阅读dble xa事务的文档,建立一些术语概念。(一)分库分表中间件用XA事务 解决跨库事务的思路
分库分表中间件对用户来说就像一个MySQL,分库分表中间件自己面对多个MySQL。
用户发出的逻辑sql,会被中间件解析成多条到不同MySQL的物理sql。
在中间件不使用任何分布式事务解决方案的时候,只是在多个MySQL上执行本地事务,和用户自己连接到MySQL上执行本地事务一致。这种最大努力尝试提交的方式是无法保证数据一致性的。
无论中间件使用xa事务还是使用本地事务,都是分库分表中间件内部自己使用的事务,业务代码访问分库分表中间件的仍然使用的是普通本地事务,这也是分库分表中间件一直在宣传的(有限)透明, 对业务代码侵入低。
这样去想,就知道分库分表中间件在用xa解决跨库事务的时候要做到的流程。
业务侧连接到中间件执行本地事务的一般步骤

  • 显式事务
start transaction / begin
DML
commit/rollback
  • 隐式事务
set autocommit=0;
DML
commit/rollback
  • autocommit开启时的单条的跨库sql

autocommit为true的单条sql原子事务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值