分布式事务-两阶段提交

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 09:34   653   0

一、获取数据源工具类

package com.terry.druid;

import javax.sql.DataSource;
import javax.sql.XADataSource;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.xa.DruidXADataSource;

public class DataSourceUtils {

 enum Type {
  USER, ORDERS
 }
 
 private final static String URL_USERS = "jdbc:mysql://localhost:3306/users?serverTimezone=UTC";
 private final static String URL_ORDERS = "jdbc:mysql://localhost:3306/orders?serverTimezone=UTC";
 private final static String USERNAME = "root";
 private final static String PASSWORD = "123456";
 
 public static DataSource getDataSource(Type type) {
  DruidDataSource dataSource = new DruidDataSource();
  if (type == Type.USER) {
   dataSource.setUrl(URL_USERS);
  } else if (type == Type.ORDERS) {
   dataSource.setUrl(URL_ORDERS);
  }
  dataSource.setUrl(URL_USERS);
  dataSource.setUsername(USERNAME);
  dataSource.setPassword(PASSWORD);
  return dataSource;
 }
 
 public static XADataSource getXADataSource(Type type) {
  DruidXADataSource xaDataSource = new DruidXADataSource();
  if (type == Type.USER) {
   xaDataSource.setUrl(URL_USERS);
  } else if (type == Type.ORDERS) {
   xaDataSource.setUrl(URL_ORDERS);
  }
  xaDataSource.setUsername(USERNAME);
  xaDataSource.setPassword(PASSWORD);
  return xaDataSource;
 }
 
 
 
}

二、实现代码

package com.terry.druid;

import java.sql.Connection;
import java.sql.Statement;

import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import com.mysql.jdbc.jdbc2.optional.MysqlXid;

public class Test {

 
 
 public static void main(String[] args) throws Exception {
  XADataSource dataSource1 = DataSourceUtils.getXADataSource(DataSourceUtils.Type.ORDERS);
  XAConnection conn1 = dataSource1.getXAConnection();
  XAResource resource1 = conn1.getXAResource();
  Connection conn11 = conn1.getConnection();
  Statement stat1 = conn11.createStatement();
  
  XADataSource dataSource2 = DataSourceUtils.getXADataSource(DataSourceUtils.Type.USER);
  XAConnection conn2 = dataSource2.getXAConnection();
  XAResource resource2 = conn2.getXAResource();
  Connection conn22 = conn2.getConnection();
  Statement stat2 = conn22.createStatement();
  
  Xid[] xids = createXID();
  Xid xid1 = xids[0];
  Xid xid2 = xids[1];
  
  int ret1 = 0;
  int ret2 = 0;
  
  String sql2 = "insert into user(name,password) values('terry', '123456')";
  String sql1 = "insert into orders(user_id,order_no) values(2, 'no123456')";
  
  resource1.start(xid1, XAResource.TMNOFLAGS);
  stat1.execute(sql1);
  resource1.end(xid1, XAResource.TMSUCCESS);
  
  resource2.start(xid2, XAResource.TMNOFLAGS);
  stat2.execute(sql2);
  resource2.end(xid2, XAResource.TMSUCCESS);
  
  ret1 = resource2.prepare(xid2);
  
  ret2 = resource1.prepare(xid1);
  
  if (ret1 == XAResource.XA_OK && ret2 == XAResource.XA_OK) {
   resource1.commit(xid1, false);
   resource2.commit(xid2, false);
  } else {
   resource1.rollback(xid1);
   resource2.rollback(xid2);
  }
  
 }
 
  static Xid[] createXID() {
         Xid xid_1 = null;
         byte[] gid_1 = new byte[1];
         byte[] bid_1 = new byte[1];
         gid_1[0] = (Byte.decode("0x01").byteValue());
         bid_1[0] = (Byte.decode("0x02").byteValue());
         xid_1 = new MysqlXid(gid_1, bid_1, 0);
  
         Xid xid_2 = null;
         byte[] gid_2 = new byte[1];
         byte[] bid_2 = new byte[1];
         gid_2[0] = (Byte.decode("0x01").byteValue());
         bid_2[0] = (Byte.decode("0x03").byteValue());
         xid_2 = new MysqlXid(gid_2, bid_2, 0);
         return new Xid[]{xid_1, xid_2};
     }
 
 
 
 private static void insertUser() throws Exception {
  Connection conn = DataSourceUtils.getDataSource(DataSourceUtils.Type.USER).getConnection();
  Statement stat = conn.createStatement();
  String sql = "insert into user(name,password) values('terry', '123456')";
  stat.execute(sql);
 }
 
 private static void insertOrder() throws Exception {
  Connection conn = DataSourceUtils.getDataSource(DataSourceUtils.Type.ORDERS).getConnection();
  Statement stat = conn.createStatement();
  String sql = "insert into orders(user_id,order_no) values(2, 'no123456')";
  stat.execute(sql);
 }
 

}

三、总结

1、分布式事务完全自己手工控制

2、commit、rollback都是自己控制

3、一个失败,都全部回滚

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP