分布式事务-两阶段提交

一、获取数据源工具类

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、一个失败,都全部回滚

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值