Distributed Transactions (c) mysql support for XA protocol

Primer

From Mysql5 start, innoDB protocol engine supports XA distributed transactions. DTP model, a TM (Transaction Manager) to manage multiple RM (resource manager), each RM maintains its own transaction branch. Before we look at the source code to see the underlying DB mysql support for XA transactions.

1. XA grammar

官网:13.3.8.1 XA Transaction SQL Syntax

. 1 XA {the START | the BEGIN} XID [ the JOIN | the RESUME ] Open XA transaction using begin to use join / resume, start do not support 2 . 3 XA the END XID [ the SUSPEND [the FOR the MIGRATE ] ] does not support the SUSPEND [the FOR the MIGRATE] . 4 . 5 XA pREPARE preparation phase of two-phase commit protocol xid 6 7 XA COMMIT xid [ ONE the pHASE ] submitted two-phase commit protocol stage, ONE behalf of the pHASE one-phase commit if only one participant rm, then the two-phase commit protocol optimization to submit a stage 8 9 XA rOLLBACK XID rollback 10 . 11 the RECOVER XA [ the CONVERT an XID ] lists all transactions in a prepared state

上面的语法中都有xid官方解释如下:

xid: gtrid [, bqual [, formatID ]]

among them,

gtrid:全局事务ID,不得超过64,建议使用十六进制数。

bqual:分支限定符(branch qualifier),如果没有提供bqual,那么默认值为空字符串'',长度不超过64,建议使用十六进制数。

formatID:是一个无符号整数,用于标记gtrid和bqual值的格式,默认为1,长度不超过64.

对应java接口:

 1 public interface Xid {
 2     int MAXGTRIDSIZE = 64;  3 int MAXBQUALSIZE = 64;  4  5 int getFormatId();  6  7 byte[] getGlobalTransactionId();  8  9 byte[] getBranchQualifier(); 10 }

2. XA state

Official website: 13.3.8.2 XA Transaction States

XA transaction state, the following steps are expanded

1. Use XA START to start an XA transaction and put it in ACTIVEthe state.

2. For a the ACTIVE XA transaction status, we can execute SQL statements constitute matters, then publish a XA END statement. XA END the transaction enters IDLEstate.

3. For an IDLE state XA transaction, you can perform an XA PREPARE statement or an XA COMMIT ... ONE PHASE statement:

  • XA PREPARE puts the transaction in PREPAREDthe state. XA RECOVER statement at this point will include the transaction's xid value in its output, because XA RECOVER lists all XA transactions in the PREPARED state.

  • XA COMMIT ... ONE PHASE (optimized for one-phase commit) to prepare and submit the transaction. xid value will not be listed XA RECOVER, because the transaction is terminated.

4. For a PREPARED state XA transaction performed XA a COMMIT statement to commit and terminate the transaction, or to perform XA ROLLBACK to roll back and terminate the transaction. 

 

 note:

With a client database connection, XA transactions and non-XA transaction (that is, local transactions) are mutually exclusive. For example, it has been carried out "XA START" command to open an XA transaction, local transaction can not be started until the XA transaction has been committed or rolled back. Conversely, if you have a local transaction started using START TRANSACTION, the XA statement can not be used until the transaction is committed or rolled back.

3. Test

 1 package study.xa;
 2 
 3 import com.mysql.jdbc.jdbc2.optional.MysqlXAConnection;
 4 import com.mysql.jdbc.jdbc2.optional.MysqlXid;
 5 
 6 import javax.sql.XAConnection;
 7 import javax.transaction.xa.XAException;
 8 import javax.transaction.xa.XAResource;
 9 import javax.transaction.xa.Xid;
10 import java.sql.Connection;
11 import java.sql.DriverManager;
12 import java.sql.PreparedStatement;
13 importjava.sql.SQLException;
 14  
15  / ** *
 16  * Distributed Transaction XAConnection analog @Description MySQL
 . 17  * @author Denny
 18 is  * Morning @date 2019/4/3 9:15
 . 19   * / 
20 is  public  class MysqlXaConnectionTest {
 21 is  
22 is      public  static  void main (String [] args) throws SQLException {
 23 is          // to true indicates XA print statements for debug ,, 
24          Boolean logXaCommands = to true ;
 25          // operator interface to obtain resource manager instance RMl 
26 is         Connection conn1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");
27         XAConnection xaConn1 = new MysqlXAConnection((com.mysql.jdbc.Connection)conn1, logXaCommands);
28         XAResource rm1 = xaConn1.getXAResource();
29 
30         // 获得资源管理器操作接口实例 RM2
31         Connection conn2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/test2", "root", "12345");
32         XAConnection xaConn2 = new MysqlXAConnection((com.mysql.jdbc.Connection)conn2, logXaCommands);
33         XAResource rm2 =xaConn2.getXAResource ();
 34 is          // the AP performs a distributed transaction request TM, TM generates a global transaction ID 
35          byte [] = the gtrid "g12345" .getBytes ();
 36          int formatid =. 1 ;
 37 [          the try {
 38 is              // = ============= each transaction performed on the branches RM1 and RM2 ====================
 39              // the TM is generated rm1 branch transaction ID 
40              byte [] = bqual1 "b00001" .getBytes ();
 41 is              Xids Xid1 = new new MysqlXid (the gtrid, bqual1, formatid);
 42 is              // . One branch of the transaction execution of TMNOFLAGS to RM1, neither TMJOIN, or TMRESUME is 
43 is              rm1.start (xid1, XAResource.TMNOFLAGS);
44              @ Business 1: Insert user table 
45              the PreparedStatement PS1 = conn1.prepareStatement ( "the INSERT INTO user the VALUES ( '99', 'user99')" );
 46 is              ps1.execute ();
 47              rm1.end (Xid1, the XAResource. TMSUCCESS is);
 48  
49              // (TM) generates the transaction branch ID rm2 
50              byte [] = bqual2 "b00002" .getBytes ();
 51 is              Xids Xid2 = new new ; MysqlXid (the gtrid, bqual2, formatid)
 52 is              // performed on the rm2 transaction branch 
53 is              rm2.start (Xid2, XAResource.TMNOFLAGS);
 54 is              // service 2: insert user_msg table 
55             PreparedStatement ps2 = conn2.prepareStatement ( "INSERT into user_msg VALUES ( '88', '99', 'user99 notes')" );
 56 is              ps2.execute ();
 57 is              rm2.end (Xid2, XAResource.TMSUCCESS);
 58  
59              // =================== two-phase commit ========================= =======
 60              // phase1: RM ask all ready to commit a transaction branch 
61              int rm1Prepare = rm1.prepare (Xid1);
 62              int rm2Prepare = rm2.prepare (Xid2);
 63              // Phase2: commit all transaction branch 
64              Boolean onePhase is = to false ;
 65              // (TM) is determined there are two transaction branch can not be optimized for one-phase commit
66              IF (rm1Prepare == XAResource.XA_OK
 67                  && rm2Prepare == XAResource.XA_OK
 68                  ) {
 69                  // all branches prepare a successful transaction, commit all transaction branch 
70                  rm1.commit (Xid1, onePhase);
 71                  rm2.commit (Xid2 , onePhase is);
 72              } the else {
 73 is                  // if the transaction branch was not successful, the rollback 
74                  rm1.rollback (Xid1);
 75                  rm1.rollback (Xid2);
 76              }
 77          } the catch (XAException with E) {
 78             // If an exception occurs, but also rollback 
79              e.printStackTrace ();
 80          }
 81      }
 82 }

Print log:

1 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA START 0x673132333435,0x623030303031,0x1
2 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA END 0x673132333435,0x623030303031,0x1
3 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA START 0x673132333435,0x623030303032,0x1
4 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA END 0x673132333435,0x623030303032,0x1
5 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA PREPARE 0x673132333435,0x623030303031,0x1
6 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA PREPARE 0x673132333435,0x623030303032,0x1
7 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA COMMIT 0x673132333435,0x623030303031,0x1
8 Tue Jun 04 17:08:18 CST 2019 DEBUG: Executing XA statement: XA COMMIT 0x673132333435,0x623030303032,0x1

 

 

===== Reference ======

http://www.tianshouzhi.com/api/tutorials/distributed_transaction/384

Guess you like

Origin www.cnblogs.com/dennyzhangdd/p/10975192.html