分布式事务 - MySQL外部XA事务
程序员文章站
2022-05-23 14:58:30
...
参考博客:http://lixiaohui.iteye.com/blog/2352645
测试实现了Java版本的XA事务代码,这里使用的SQL实现,当然MySQL驱动实现了JTA,也可以使用MysqlXADataSource 做XA事务
首先检查MySQL是否开启XA事务:
SHOW VARIABLES LIKE '%xa%'
ON表示开启
数据库的XA事务实现都是数据库本身实现的,在多个不同数据库操作的时候由Java客户端和数据库驱动作为 <资源管理器> 所以不用操心MySQL是怎么配置协调多台数据库的
下面的例子和参考博客类似
A表中有一个用户余额为1000块钱
B表中有一个用户余额为1000块钱
3次修改后 A表余额 700 B表余额 1300
其中两次修改是由事务回滚无效
代码如下:
package com.myself.mysqlxa;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.UUID;
/**
* @author yangankang
*/
public class XARun {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws SQLException {
XARun xaRun = new XARun();
xaRun.xaSuccess(false, false);
xaRun.xaSuccess(true, false);
xaRun.xaSuccess(false, true);
}
public static Connection getConnection(String ip, String db, String user, String password, int port) throws SQLException {
String url = "jdbc:mysql://" + ip + ":" + port + "/" + db + "?"
+ "user=" + user + "&password=" + password + "&useUnicode=true&characterEncoding=UTF8&autoReconnect=true";
return DriverManager.getConnection(url);
}
private Connection getC1() throws SQLException {
return XARun.getConnection("localhost", "mysql_xa", "root", "123456", 3307);
}
private Connection getC2() throws SQLException {
return XARun.getConnection("localhost", "mysql_xa", "root", "123456", 3306);
}
/**
* 假设两个不同的数据库的money是一样的1000
*
* @param ep1
* @param ep2
* @throws SQLException
*/
public void xaSuccess(boolean ep1, boolean ep2) throws SQLException {
String xid = UUID.randomUUID().toString().replace("-", "");
Connection c1 = null;
Connection c2 = null;
Statement s1 = null;
Statement s2 = null;
try {
c1 = this.getC1();
c2 = this.getC2();
s1 = c1.createStatement();
s2 = c2.createStatement();
s1.execute("XA START '" + xid + "'");
s2.execute("XA START '" + xid + "'");
s1.execute("UPDATE `user` SET `money` = `money` - 300 WHERE `name`='秦明涛'");
s2.execute("UPDATE `user` SET `money` = `money` + 300 WHERE `name`='杨安康'");
s1.execute("XA END " + "'" + xid + "'");
s1.execute("XA PREPARE " + "'" + xid + "'");
s2.execute("XA END " + "'" + xid + "'");
s2.execute("XA PREPARE " + "'" + xid + "'");
if (ep1) {
throw new RuntimeException("事务回滚1");
}
s1.execute("XA COMMIT " + "'" + xid + "'");
if (ep2) {
throw new RuntimeException("事务回滚2");
}
s2.execute("XA COMMIT " + "'" + xid + "'");
} catch (Exception e) {
e.printStackTrace();
if (s1 != null) {
s1.execute("XA ROLLBACK " + "'" + xid + "'");
}
if (s2 != null) {
s2.execute("XA ROLLBACK " + "'" + xid + "'");
}
} finally {
try {
if (c1 != null) c1.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (c2 != null) c2.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
这就是MySQL的XA事务
上一篇: 卖萌教大家怎么成为编程牛人
下一篇: MySQL 分布式事务 XA 语法