分布式事务(三)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 ...
随机推荐
- 九度oj 题目1202:排序
题目1202:排序 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:28802 解决:9408 题目描述: 对输入的n个数进行排序并输出. 输入: 输入的第一行包括一个整数n(1<=n ...
- cmake打印变量值
看下面的例子,我们在cmake定义了一个变量“USER_KEY”,并打印此变量值.status表示这是一般的打印信息,我们还可以设置为“ERROR”,表示这是一种错误打印信息. SET(USER_KE ...
- POJ3352-Road Construction(边连通分量)
It's almost summer time, and that means that it's almost summer construction time! This year, the go ...
- EasyUI单击行数据时动态编写editor
$.extend($.fn.treegrid.methods, { addEditor: function (jq, param) { if (param instanceof Array) { $. ...
- 2017 CCPC 杭州 HDU6265B 积性函数
题目链接 http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf B题 数论题 h(n)=∑ d|n φ(d) × ...
- hdu - 1150 Machine Schedule (二分图匹配最小点覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=1150 有两种机器,A机器有n种模式,B机器有m种模式,现在有k个任务需要执行,没切换一个任务机器就需要重启一次, ...
- Google Protocol Buffer 的使用(一)
一.什么是Google Protocol Buffer下面是官网给的解释:Protocol buffers are a language-neutral, platform-neutral exten ...
- server证书安装配置指南(Tomcat 6)
一. 生成证书请求 1. 安装JDK 安装Tomcat须要JDK支持. 假设您还没有JDK的安装.则能够參考 Java SE Development Kit (JDK) 下载. 下载地址: ...
- 怎样把UCos-ii_在STM32上的移植
下载代码 stm32 标准外设库是 stm32 全系列芯片的外设驱动,有了它能够大大加速我们 开发 stm32. 首先从 st 公司的站点下载最新的 stm32 标准外设库,写本文时最新的版本号是 V ...
- Sound Card Chip
DELL sigmatel stac Hewlett-packard conexant High Definition Audio chip lenovo(IBM) Analo Devic ...