正文
2阶段(2PC)提交方案:
实现原理:基于XA规范搞的一套分布式事务的理论,也可以叫做一套规范,或者是协议。
(1)准备阶段(Prepare phase):事务管理器给每个参与者发送prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo,此时事务没有提交。
(2)提交阶段(Commit phase):如果事务管理器接收了参与者执行失败或者超时消息时,直接给每个参与者发送回滚消息,
否则发送提交消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。
代码实现参考:
public static void main(String[] args) throws SQLException {
//true表示打印XA语句,,用于调试
boolean logXaCommands = true;
// 获得资源管理器操作接口实例 RM1
Connection conn1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_user", "root", "root");
XAConnection xaConn1 = new MysqlXAConnection((com.mysql.jdbc.Connection) conn1, logXaCommands);
XAResource rm1 = xaConn1.getXAResource();
// 获得资源管理器操作接口实例 RM2
Connection conn2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_account", "root", "root");
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 {
// TM生成rm1上的事务分支id
byte[] bqual1 = "b00001".getBytes();
Xid xid1 = new MysqlXid(gtrid, bqual1, formatId);
// 执行rm1上的事务分支
rm1.start(xid1, XAResource.TMNOFLAGS);
PreparedStatement ps1 = conn1.prepareStatement("INSERT into user(name) VALUES ('test')");
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);
PreparedStatement ps2 = conn2.prepareStatement("INSERT into account(user_id,money) VALUES (1,10000000)");
ps2.execute();
rm2.end(xid2, XAResource.TMSUCCESS);
// 两阶段提交
// phase1:询问所有的RM 准备提交事务分支
int rm1_prepare = rm1.prepare(xid1);
int rm2_prepare = rm2.prepare(xid2);
// phase2:提交所有事务分支
boolean onePhase = false;
//TM判断有2个事务分支,所以不能优化为一阶段提交
if (rm1_prepare == XAResource.XA_OK && rm2_prepare == XAResource.XA_OK) {
rm1.commit(xid1, onePhase);
rm2.commit(xid2, onePhase);
} else {
//如果有事务分支没有成功,则回滚
rm1.rollback(xid1);
rm2.rollback(xid2);
}
} catch (XAException e) {
e.printStackTrace();
}
}
1.最好pom引入开源的分布式事务管理器,如Atomikos作为本地事务管理器。如:Spring Boot集成atomikos快速入门Demo
2.在分布式环境中,每个服务配置 Atomikos 作为本地事务管理器,但是全局事务的管理和协调是由一个独立的分布式事务协调器(DTC)来完成。
3.在分布式环境中,独立的分布式事务协调器(DTC)通常是一个单独的服务或组件。通常情况下,
项目除了引入 Atomikos 作为本地事务管理器之外,还需要考虑如何部署和配置这个分布式事务协调器。
4.在分布式环境中,确保分布式事务的一致性和可靠性需要配合使用本地事务管理器(如 Atomikos)和一个独立的分布式事务协调器(DTC)。