ShardingSphere has defined an SPI for distributed transactions, ShardingTransactionManager. Sharding-JDBC and Sharding-Proxy are two accesses for distributed transactions. XAShardingTransactionManager
is its XA implementation, which can be added to ShardingSphere distributed ecology by introducing sharding-transaction-xa-core
dependency. XAShardingTransactionManager manages and adapts to actual datasource; it delegates begin/commit/rollback in access transactions to XA managers.
Receiving set autoCommit=0 in the access, XAShardingTransactionManager will use XA transaction managers to start overall XA transactions, which is usually marked by XID.
After ShardingSphere parses, optimizes or routes, it will generate sharding SQLUnit of logic SQL. The execution engine will both create connection for each actual SQL and register the corresponding XAResource to the current XA transaction. In this phase, the transaction manager will send XAResource.start
to the database and all the SQL before XAResource.end
will be marked as XA transactions.
For example:
XAResource1.start ## execute in the enlist phase
statement.execute("sql1");
statement.execute("sql2");
XAResource1.end ## execute in the commit phase
sql1 and sql2 in it will be marked as XA transactions.
After XAShardingTransactionManager receives the commit command in the access, it will delegate it to the actual XA manager. It will collect all the registered XAResource in the thread, before sending XAResource.end
to mark the boundary for the XA transaction. Then it will send prepare command one by one to collect votes from XAResource. If all the XAResource feedback is OK, it will send commit command to finally finish it. If there is any No XAResource feedback, it will send rollback command to roll back. After sending the commit command, all XAResource exceptions will be submitted again according to the recovery log to ensure the atomicity and high consistency.
For example:
XAResource1.prepare ## ack: yes
XAResource2.prepare ## ack: yes
XAResource1.commit
XAResource2.commit
XAResource1.prepare ## ack: yes
XAResource2.prepare ## ack: no
XAResource1.rollback
XAResource2.rollback