分布式事务(三)mysql对XA协议的支持
系列目录
引子
从Mysql5开始,innoDB引擎支持XA协议的分布式事务。DTP模型中,一个TM(事务管理器管理)管理多个RM(资源管理器),每个RM维护自己的事务分支。在看源码之前我们看一下底层DB mysql对XA事务的支持。
1. XA语法
官网:13.3.8.1 XA Transaction SQL Syntax
1 XA {START|BEGIN} xid [JOIN|RESUME] 开启XA事务,使用begin才能使用join/resume,start不支持
2
3 XA END xid [SUSPEND [FOR MIGRATE]] 不支持SUSPEND [FOR MIGRATE]
4
5 XA PREPARE xid 二阶段提交的准备阶段
6
7 XA COMMIT xid [ONE PHASE] 二阶段提交的提交阶段,ONE PHASE代表一阶段提交,如果只有一个rm参与者,那么二阶段提交优化为一阶段提交
8
9 XA ROLLBACK xid 回滚
10
11 XA RECOVER [CONVERT XID] 列出所有处于prepared状态的事务
上面的语法中都有xid官方解释如下:
xid: gtrid [, bqual [, formatID ]]
其中,
gtrid:全局事务ID,不得超过64,建议使用十六进制数。
bqual:分支限定符(branch qualifier),如果没有提供bqual,那么默认值为空字符串'',长度不超过64
,建议使用十六进制数。
formatID:是一个无符号整数,用于标记gtrid和bqual值的格式,默认为1,长度不超过64.
对应java接口:
1 public interface Xid {
2 int MAXGTRIDSIZE = 64;
3 int MAXBQUALSIZE = 64;
4
5 int getFormatId();
6
7 byte[] getGlobalTransactionId();
8
9 byte[] getBranchQualifier();
10 }
2. XA状态
官网:13.3.8.2 XA Transaction States
XA事务的状态,按照如下步骤进行展开
1. 使用XA START来启动一个XA事务,并把它置于ACTIVE
状态。
2. 对于一个ACTIVE状态的 XA事务,我们可以执行构成事务的SQL语句,然后发布一个XA END语句。XA END使事务进入IDLE
状态。
3. 对于一个IDLE 状态XA事务,可以执行一个XA PREPARE语句或一个XA COMMIT…ONE PHASE语句:
XA PREPARE把事务放入
PREPARED
状态。在此点上的XA RECOVER语句将在其输出中包括事务的xid值,因为XA RECOVER会列出处于PREPARED状态的所有XA事务。XA COMMIT…ONE PHASE(优化成一阶段提交)用于预备和提交事务。xid值将不会被XA RECOVER列出,因为事务终止。
4. 对于一个PREPARED状态的 XA事务,执行XA COMMIT语句来提交和终止事务,或者执行XA ROLLBACK来回滚并终止事务。
注意:
同一个客户端数据库连接,XA事务和非XA事务(即本地事务)是互斥的。例如,已经执行了”XA START”命令来开启一个XA事务,则本地事务不会被启动,直到XA事务已经被提交或被 回滚为止。相反的,如果已经使用START TRANSACTION启动一个本地事务,则XA语句不能被使用,直到该事务被提交或被 回滚为止。
3. 测试
package study.xa; import com.mysql.jdbc.jdbc2.optional.MysqlXAConnection;
import com.mysql.jdbc.jdbc2.optional.MysqlXid; import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; /***
* @Description mysql分布式事务XAConnection模拟
* @author denny
* @date 2019/4/3 上午9:15
*/
public class MysqlXaConnectionTest { public static void main(String[] args) throws SQLException {
//true表示打印XA语句,,用于调试
boolean logXaCommands = true;
// 获得资源管理器操作接口实例 RM1
Connection conn1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");
XAConnection xaConn1 = new MysqlXAConnection((com.mysql.jdbc.Connection)conn1, logXaCommands);
XAResource rm1 = xaConn1.getXAResource(); // 获得资源管理器操作接口实例 RM2
Connection conn2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/test2", "root", "12345");
XAConnection xaConn2 = new MysqlXAConnection((com.mysql.jdbc.Connection)conn2, logXaCommands);
XAResource rm2 = xaConn2.getXAResource();
// AP请求TM执行一个分布式事务,TM生成全局事务id
byte[] gtrid = "g12345".getBytes();
int formatId = 1;
try {
// ==============分别执行RM1和RM2上的事务分支====================
// TM生成rm1上的事务分支id
byte[] bqual1 = "b00001".getBytes();
Xid xid1 = new MysqlXid(gtrid, bqual1, formatId);
// 执行rm1上的事务分支 One of TMNOFLAGS, TMJOIN, or TMRESUME.
rm1.start(xid1, XAResource.TMNOFLAGS);
// 业务1:插入user表
PreparedStatement ps1 = conn1.prepareStatement("INSERT into user VALUES ('99', 'user99')");
ps1.execute();
rm1.end(xid1, XAResource.TMSUCCESS); // TM生成rm2上的事务分支id
byte[] bqual2 = "b00002".getBytes();
Xid xid2 = new MysqlXid(gtrid, bqual2, formatId);
// 执行rm2上的事务分支
rm2.start(xid2, XAResource.TMNOFLAGS);
// 业务2:插入user_msg表
PreparedStatement ps2 = conn2.prepareStatement("INSERT into user_msg VALUES ('88', '99', 'user99的备注')");
ps2.execute();
rm2.end(xid2, XAResource.TMSUCCESS); // ===================两阶段提交================================
// phase1:询问所有的RM 准备提交事务分支
int rm1Prepare = rm1.prepare(xid1);
int rm2Prepare = rm2.prepare(xid2);
// phase2:提交所有事务分支
boolean onePhase = false;
//TM判断有2个事务分支,所以不能优化为一阶段提交
if (rm1Prepare == XAResource.XA_OK
&& rm2Prepare == XAResource.XA_OK
) {
//所有事务分支都prepare成功,提交所有事务分支
rm1.commit(xid1, onePhase);
rm2.commit(xid2, onePhase);
} else {
//如果有事务分支没有成功,则回滚
rm1.rollback(xid1);
rm1.rollback(xid2);
}
} catch (XAException e) {
// 如果出现异常,也要进行回滚
e.printStackTrace();
}
}
}
打印日志:
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA START 0x673132333435,0x623030303031,0x1
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA END 0x673132333435,0x623030303031,0x1
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA START 0x673132333435,0x623030303032,0x1
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA END 0x673132333435,0x623030303032,0x1
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA PREPARE 0x673132333435,0x623030303031,0x1
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA PREPARE 0x673132333435,0x623030303032,0x1
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA COMMIT 0x673132333435,0x623030303031,0x1
Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA COMMIT 0x673132333435,0x623030303032,0x1
=====参考======
http://www.tianshouzhi.com/api/tutorials/distributed_transaction/384
分布式事务(三)mysql对XA协议的支持的更多相关文章
- [转帖]分布式事务之解决方案(XA和2PC)
分布式事务之解决方案(XA和2PC) https://zhuanlan.zhihu.com/p/93459200 3. 分布式事务解决方案之2PC(两阶段提交) 针对不同的分布式场景业界常见的解决方案 ...
- 【转帖】分布式事务之解决方案(XA和2PC)
分布式事务之解决方案(XA和2PC) https://zhuanlan.zhihu.com/p/93459200 博彦信息技术有限公司 java工程师 3. 分布式事务解决方案之2PC(两阶段提交 ...
- 分布式事务之解决方案(XA和2PC)
3. 分布式事务解决方案之2PC(两阶段提交) 针对不同的分布式场景业界常见的解决方案有2PC.TCC.可靠消息最终一致性.最大努力通知这几种. 3.1. 什么是2PC 2PC即两阶段提交协议,是将整 ...
- 分布式事务(二)Java事务API(JTA)规范
一.引子 既然出现了分布式场景(DTP模型), 大java也及时制定出一套规范来给各大应用服务器.数据库/mq等厂商使用,以方便管理互通--->JTA闪亮登场.JTA(Java Transact ...
- 了解一下Mysql分布式事务及优缺点、使用案例(php+mysql)
在开发中,为了降低单点压力,通常会根据业务情况进行分表分库,将表分布在不同的库中(库可能分布在不同的机器上),但是一个业务场景可能会同时处理两个表的操作.在这种场景下,事务的提交会变得相对复杂,因为多 ...
- 分布式事务、XA、两阶段提交、一阶段提交
本文原文连接:http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的分布式事务的规范 ...
- JTA 使用 MySQL 分布式事务
假定在MySQL实例1上有表 create table person( id int, name ) ) MySQL实例2上也有一张同样的表,现在从实例1中的 person 表中删除一条数据,并把这条 ...
- XA事务与MySQL
XA事务就是两阶段提交的一种实现方式 XA规范主要定义了事务管理器TM,和资源管理器RM之间的接口 根据2PC的规范,将一次事务分割成两个阶段 1. prepare阶段 TM向所有RM发送prepar ...
- Spring Cloud Alibaba | 微服务分布式事务之Seata
Spring Cloud Alibaba | 微服务分布式事务之Seata 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Green ...
随机推荐
- 7-10 公路村村通(30 分)(最小生成树Prim算法)
7-10 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1 ...
- shit IE & no table `border-collapse: collapse;`
shit IE no table border-collapse: collapse; /* IE & shit table & border-collapse: collapse; ...
- PKCS填充方式
1)RSA_PKCS1_PADDING 填充模式,最常用的模式要求: 输入 必须 比 RSA 钥模长(modulus) 短至少11个字节, 也就是 RSA_size(rsa) – 11.如果输入的明文 ...
- hdu - 1195 Open the Lock (bfs) && hdu 1973 Prime Path (bfs)
http://acm.hdu.edu.cn/showproblem.php?pid=1195 这道题虽然只是从四个数到四个数,但是状态很多,开始一直不知道怎么下手,关键就是如何划分这些状态,确保每一个 ...
- 1085 数字游戏 2003年NOIP全国联赛普及组
丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分 ...
- Surprising Strings
Surprising Strings Time Limit: 1000MS Memory Limit: 65536K Total Submissions: Accepted: Description ...
- POJ 1064_Cable master
题意: 给定一系列长度的电缆,将他们切成K条相等长度的电缆,问每条最长有多长? 分析: 对长度进行二分,判断能否满足K条. 二分搜索: 在求解最大化或最小化问题中,能够比较简单的判断条件是否满足,那么 ...
- codeforces 762E(cdq分治)
题意: n个电台,每个电台有三个属性xi, ri, fi.分别代表电台的坐标,电台的播报范围,以及播报的频率. 对于一对电台i, j,若min(ri, rj) >= |xi - xj|,那么他们 ...
- Xcode iOS9.3 配置包 iOS10.0 配置包 iOS10.2 配置包 could not find developer disk image
在Finder状态下前往目录.快捷键:shift+command+G,填写路径/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS ...
- react 组件之间的通信
react推崇的是单向数据流,自上而下进行数据的传递,但是由下而上或者不在一条数据流上的组件之间的通信就会变的复杂.解决通信问题的方法很多,如果只是父子级关系,父级可以将一个回调函数当作属性传递给子级 ...