XA分布式事务,很显然是发生在多台db上的,
Java XA分布式事务实现如下:
依赖jar包:
<dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc</artifactId> <version>3.9.3</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency>
Java 代码如下:
import java.sql.Connection; import java.sql.PreparedStatement; import javax.sql.XAConnection; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; import com.atomikos.icatch.jta.UserTransactionManager; import com.atomikos.jdbc.AtomikosDataSourceBean; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; import com.mysql.jdbc.jdbc2.optional.MysqlXid; public class DataSourceTools { protected static MysqlXADataSource getMysqlXADataSource1() { MysqlXADataSource mysqlXADataSource = new MysqlXADataSource(); mysqlXADataSource.setURL("jdbc:mysql://127.0.0.1:3306/db1"); mysqlXADataSource.setUser("root"); mysqlXADataSource.setPassword("1"); return mysqlXADataSource; } protected static MysqlXADataSource getMysqlXADataSource2() { MysqlXADataSource mysqlXADataSource = new MysqlXADataSource(); mysqlXADataSource.setURL("jdbc:mysql://127.0.0.1:3306/db2"); mysqlXADataSource.setUser("root"); mysqlXADataSource.setPassword("1"); return mysqlXADataSource; } public static AtomikosDataSourceBean getXADataSource1() { AtomikosDataSourceBean dataSourceBean = new AtomikosDataSourceBean(); dataSourceBean.setUniqueResourceName("dn1"); dataSourceBean.setXaDataSource(getMysqlXADataSource1()); dataSourceBean.setXaDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"); return dataSourceBean; } public static AtomikosDataSourceBean getXADataSource2() { AtomikosDataSourceBean dataSourceBean = new AtomikosDataSourceBean(); dataSourceBean.setUniqueResourceName("dn2"); dataSourceBean.setXaDataSource(getMysqlXADataSource2()); /* * Properties xaProperties = new Properties(); * xaProperties.setProperty("url", * "jdbc:mysql://10.0.0.104:8066/TESTDB"); * xaProperties.setProperty("user", "user"); * xaProperties.setProperty("password", "user"); * dataSourceBean.setXaProperties(xaProperties); */ dataSourceBean.setXaDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"); return dataSourceBean; } public static UserTransactionManager getUserTransactionManager() throws Exception { return new UserTransactionManager(); } public static void main(String[] args) throws Exception { AtomikosDataSourceBean atomikos1 = getXADataSource1() ; AtomikosDataSourceBean atomikos2 = getXADataSource2() ; XAConnection xaCon1 = atomikos1.getXaDataSource().getXAConnection(); XAConnection xaCon2 = atomikos2.getXaDataSource().getXAConnection(); Connection conn1 = xaCon1.getConnection(); Connection conn2 = xaCon2.getConnection(); XAResource xaResource1 = xaCon1.getXAResource(); XAResource xaResource2 = xaCon2.getXAResource(); Xid xid1 = new MysqlXid(new byte[]{0x01}, new byte[]{0x02} , 0) ; Xid xid2 = new MysqlXid(new byte[]{0x01}, new byte[]{0x03}, 0); try { xaResource1.start(xid1, XAResource.TMNOFLAGS); PreparedStatement ps1 = conn1.prepareStatement("INSERT INTO tb_role(NAME,available) VALUES('3' , 2)"); ps1.executeUpdate() ; xaResource1.end(xid1, XAResource.TMSUCCESS); xaResource2.start(xid2, XAResource.TMNOFLAGS); PreparedStatement ps2 = conn2.prepareStatement("INSERT INTO tb_role(NAME,available) VALUES('4' , 1)"); ps2.executeUpdate() ; xaResource2.end(xid2, XAResource.TMSUCCESS); int prepare1 = xaResource1.prepare( xid1 ) ; int prepare2 = xaResource2.prepare( xid2 ) ; if(prepare1 == XAResource.XA_OK && prepare2 == XAResource.XA_OK){ xaResource1.commit(xid1, false); System.out.println("suc1"); xaResource2.commit(xid2, false); System.out.println("suc2"); }else{ System.out.println("rollback"); xaResource1.rollback(xid1); xaResource2.rollback(xid2); } } catch (Exception e) { e.printStackTrace(); xaResource1.rollback(xid1); xaResource2.rollback(xid2); } } }
mysql XA事务写法
mysql> XA START 'xatest'; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO mytable (i) VALUES(10); Query OK, 1 row affected (0.04 sec) mysql> XA END 'xatest'; Query OK, 0 rows affected (0.00 sec) mysql> XA PREPARE 'xatest'; Query OK, 0 rows affected (0.00 sec) mysql> XA COMMIT 'xatest'; Query OK, 0 rows affected (0.00 sec)