2階段(2PC)提交方案:
實現原理:基於XA規範搞的一套分散式事務的理論,也可以叫做一套規範,或者是協議。
(1)準備階段(Prepare phase):事務管理器給每個參與者傳送prepare訊息,每個資料庫參與者在本地執行事務,並寫本地的Undo/Redo,此時事務沒有提交。
(2)提交階段(Commit phase):如果事務管理器接收了參與者執行失敗或者超時訊息時,直接給每個參與者傳送回滾訊息,
否則傳送提交訊息;參與者根據事務管理器的指令執行提交或者回滾操作,並釋放事務處理過程中使用的鎖資源。
程式碼實現參考:
public static void main(String[] args) throws SQLException, XAException {
// 獲得資源管理器操作介面例項 RM1
Connection conn1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/dev", "root", "123456");
XAConnection xaConn1 = new MysqlXAConnection((JdbcConnection) conn1, true);
XAResource db1 = xaConn1.getXAResource();
// 獲得資源管理器操作介面例項 RM2
Connection conn2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/db2", "root", "123456");
XAConnection xaConn2 = new MysqlXAConnection((JdbcConnection) conn2, true);
XAResource db2 = xaConn2.getXAResource();
// 應用程式 請求事務管理器 執行一個分散式事務,事務管理器 生成全域性事務id
byte[] gtrid = "g12345".getBytes();
Xid id1 = new MysqlXid(gtrid, "b00001".getBytes(), 1); // 事務管理器生成 db1上的事務分支id
Xid id2 = new MysqlXid(gtrid, "b00002".getBytes(), 1); // 事務管理器生成db2上的事務分支id
try {
// 執行db1上的事務分支
db1.start(id1, XAResource.TMNOFLAGS);
PreparedStatement ps1 = conn1.prepareStatement("INSERT into user_info(user_id, user_name) VALUES ('5', 'test')");
ps1.execute();
db1.end(id1, XAResource.TMSUCCESS);
// 執行db2上的事務分支
db2.start(id2, XAResource.TMNOFLAGS);
PreparedStatement ps2 = conn2.prepareStatement("INSERT into accounts(userId, accountNumber) VALUES (2, 10000)");
ps2.execute();
db2.end(id2, XAResource.TMSUCCESS);
// 準備兩階段提交 phase1:詢問所有的RM 準備提交事務分支
int rm1Prepare = db1.prepare(id1);
int rm2Prepare = db2.prepare(id2);
//提交所有事務分支, TM判斷有2個事務分支,所以不能最佳化為一階段提交
if (rm1Prepare == XAResource.XA_OK && rm2Prepare == XAResource.XA_OK) {
db1.commit(id1, false);
db2.commit(id2, false);
System.out.println("成功");
} else {
System.out.println("如果有事務分支沒有成功,則回滾");
db1.rollback(id1);
db2.rollback(id2);
}
int a = 1/0;
} catch (Exception e) {
e.printStackTrace();
db1.rollback(id1);
db2.rollback(id2);
System.out.println("異常error");
}
}
1.最好pom引入開源的分散式事務管理器,如Atomikos作為本地事務管理器。如:Spring Boot整合atomikos快速入門Demo
2.在分散式環境中,每個服務配置 Atomikos 作為本地事務管理器,但是全域性事務的管理和協調是由一個獨立的分散式事務協調器(DTC)來完成。
3.在分散式環境中,獨立的分散式事務協調器(DTC)通常是一個單獨的服務或元件。通常情況下,專案除了引入 Atomikos 作為本地事務管理器之外,還需要考慮如何部署和配置這個分散式事務協調器。
4.在分散式環境中,確保分散式事務的一致性和可靠性需要配合使用本地事務管理器(如 Atomikos)和一個獨立的分散式事務協調器(DTC)。