What is the use of ShardingTransactionManager in sharding-jdbc
This article will explain in detail what is the use of ShardingTransactionManager in sharding-jdbc, and the content of the article is of high quality, so the editor will share it with you for reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
ShardingTransactionManager
Incubator-shardingsphere-4.0.0-RC1/sharding-transaction/sharding-transaction-core/src/main/java/org/apache/shardingsphere/transaction/spi/ShardingTransactionManager.java
Public interface ShardingTransactionManager extends AutoCloseable {/ * * Initialize sharding transaction manager. * * @ param databaseType database type * @ param resourceDataSources resource data sources * / void init (DatabaseType databaseType, Collection resourceDataSources); / * * Get transaction type. * * @ return transaction type * / TransactionType getTransactionType (); / * * Judge is in transaction or not. * * @ return in transaction or not * / boolean isInTransaction (); / * * Get transactional connection. * * @ param dataSourceName data source name * @ return connection * @ throws SQLException SQL exception * / Connection getConnection (String dataSourceName) throws SQLException; / * Begin transaction. * / void begin (); / * * Commit transaction. * / void commit (); / * * Rollback transaction. * / void rollback ();}
ShardingTransactionManager inherits the AutoCloseable interface, which defines init, getTransactionType, isInTransaction, getConnection, begin, commit, rollback methods
XAShardingTransactionManager
Incubator-shardingsphere-4.0.0-RC1/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/XAShardingTransactionManager.java
Public final class XAShardingTransactionManager implements ShardingTransactionManager {private final Map singleXADataSourceMap = new HashMap (); private final XATransactionManager xaTransactionManager = XATransactionManagerLoader.getInstance () .getTransactionManager (); private ThreadLocal enlistedXAResource = new ThreadLocal () {@ Override public List initialValue () {return new LinkedList ();}} @ Override public void init (final DatabaseType databaseType, final Collection resourceDataSources) {for (ResourceDataSource each: resourceDataSources) {DataSource dataSource = each.getDataSource (); if (dataSource instanceof AtomikosDataSourceBean) {continue;} SingleXADataSource singleXADataSource = new SingleXADataSource (databaseType, each.getUniqueResourceName (), dataSource); singleXADataSourceMap.put (each.getOriginalName (), singleXADataSource) XaTransactionManager.registerRecoveryResource (each.getUniqueResourceName (), singleXADataSource.getXaDataSource ());} xaTransactionManager.init ();} @ Override public TransactionType getTransactionType () {return TransactionType.XA;} @ SneakyThrows @ Override public boolean isInTransaction () {return Status.STATUS_NO_TRANSACTION! = xaTransactionManager.getTransactionManager () .getStatus () } @ SneakyThrows @ Override public Connection getConnection (final String dataSourceName) {SingleXAConnection singleXAConnection = singleXADataSourceMap.get (dataSourceName) .getXAConnection (); if (! enlistedXAResource.get () .contains (dataSourceName)) {xaTransactionManager.enlistResource (singleXAConnection.getXAResource ()); enlistedXAResource.get () .add (dataSourceName);} return singleXAConnection.getConnection () } @ SneakyThrows @ Override public void begin () {xaTransactionManager.getTransactionManager () .begin ();} @ SneakyThrows @ Override public void commit () {try {xaTransactionManager.getTransactionManager () .commit ();} finally {enlistedXAResource.remove () }} @ SneakyThrows @ Override public void rollback () {try {xaTransactionManager.getTransactionManager (). Rollback ();} finally {enlistedXAResource.remove ();} @ Override public void close () throws Exception {for (SingleXADataSource each: singleXADataSourceMap.values ()) {xaTransactionManager.removeRecoveryResource (each.getResourceName (), each.getXaDataSource ()) } singleXADataSourceMap.clear (); xaTransactionManager.close (); enlistedXAResource = null;}}
XAShardingTransactionManager implements the ShardingTransactionManager interface, which has three attributes: singleXADataSourceMap, xaTransactionManager and enlistedXAResource, which are initialized by its init method.
The getTransactionType method returns the TransactionType.XA;isInTransaction method, which is judged by xaTransactionManager.getTransactionManager (). GetStatus (); the getConnection method takes the singleXAConnection from the singleXADataSourceMap and executes its getConnection method
The begin method executes xaTransactionManager.getTransactionManager () .begin (); the commit method calls xaTransactionManager.getTransactionManager () .commit (), which executes enlistedXAResource.remove () in finally; the rollback method calls xaTransactionManager.getTransactionManager () .rollback (), which also executes enlistedXAResource.remove () in finally; and the close method executes xaTransactionManager.removeRecoveryResource, singleXADataSourceMap.clear (), xaTransactionManager.close ().
XAShardingTransactionManagerTest
Incubator-shardingsphere-4.0.0-RC1/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/XAShardingTransactionManagerTest.java
@ RunWith (MockitoJUnitRunner.class) public final class XAShardingTransactionManagerTest {private XAShardingTransactionManager xaShardingTransactionManager = new XAShardingTransactionManager (); @ Mock private XATransactionManager xaTransactionManager; @ Mock private TransactionManager transactionManager; @ Before public void setUp () {when (xaTransactionManager.getTransactionManager ()) .thenReturn (transactionManager); ReflectiveUtil.setProperty (xaShardingTransactionManager, "xaTransactionManager", xaTransactionManager) } @ Test public void assertGetTransactionType () {assertThat (xaShardingTransactionManager.getTransactionType (), is (TransactionType.XA));} @ Test public void assertRegisterXATransactionalDataSources () {Collection resourceDataSources = createResourceDataSources (DruidXADataSource.class, DatabaseType.MySQL); xaShardingTransactionManager.init (DatabaseType.MySQL, resourceDataSources); for (ResourceDataSource each: resourceDataSources) {verify (xaTransactionManager) .registerRecoveryResource (each.getUniqueResourceName (), (XADataSource) each.getDataSource ()) } @ Test public void assertRegisterAtomikosDataSourceBeans () {xaShardingTransactionManager.init (DatabaseType.MySQL, createAtomikosDataSourceBeanResource ()); verify (xaTransactionManager, times (0)) .registerRecoveryResource (anyString (), any (XADataSource.class));} @ Test public void assertRegisterNoneXATransactionalDAtaSources () {Collection resourceDataSources = createResourceDataSources (HikariDataSource.class, DatabaseType.MySQL); xaShardingTransactionManager.init (DatabaseType.MySQL, resourceDataSources); Map cachedXADatasourceMap = getCachedSingleXADataSourceMap () AssertThat (cachedXADatasourceMap.size (), is (2));} @ Test public void assertIsInTransaction () throws SystemException {when (transactionManager.getStatus ()) .thenReturn (Status.STATUS_ACTIVE); assertTrue (xaShardingTransactionManager.isInTransaction ());} @ Test public void assertIsNotInTransaction () throws SystemException {when (transactionManager.getStatus ()) .thenReturn (Status.STATUS_NO_TRANSACTION); assertFalse (xaShardingTransactionManager.isInTransaction ()) } @ Test public void assertGetConnection () {setCachedSingleXADataSourceMap ("ds1"); Connection actual = xaShardingTransactionManager.getConnection ("ds1"); assertThat (actual, instanceOf (Connection.class)); verify (xaTransactionManager) .enlistResource (any (SingleXAResource.class));} @ Test public void assertGetConnectionWithoutEnlist () {setCachedSingleXADataSourceMap ("ds1"); Connection actual = xaShardingTransactionManager.getConnection ("ds1") AssertThat (actual, instanceOf (Connection.class)); xaShardingTransactionManager.getConnection ("ds1"); assertThat (actual, instanceOf (Connection.class)); verify (xaTransactionManager) .enlistResource (any (SingleXAResource.class));} @ Test public void assertClose () throws Exception {setCachedSingleXADataSourceMap ("ds1"); xaShardingTransactionManager.close (); Map cachedSingleXADataSourceMap = getCachedSingleXADataSourceMap () Verify (xaTransactionManager) .removeRecoveryResource (anyString (), any (XADataSource.class)); assertThat (cachedSingleXADataSourceMap.size (), is (0));} @ SneakyThrows @ SuppressWarnings ("unchecked") private Map getCachedSingleXADataSourceMap () {Field field = xaShardingTransactionManager.getClass (). GetDeclaredField ("singleXADataSourceMap"); field.setAccessible (true); return (Map) field.get (xaShardingTransactionManager) @ SneakyThrows private void setCachedSingleXADataSourceMap (final String datasourceName) {Field field = xaShardingTransactionManager.getClass () .getDeclaredField ("singleXADataSourceMap"); field.setAccessible (true); field.set (xaShardingTransactionManager, createMockSingleXADataSourceMap (datasourceName));} @ SneakyThrows private Map createMockSingleXADataSourceMap (final String datasourceName) {SingleXADataSource singleXADataSource = mock (SingleXADataSource.class); SingleXAConnection singleXAConnection = mock (SingleXAConnection.class); XADataSource xaDataSource = mock (XADataSource.class) SingleXAResource singleXAResource = mock (SingleXAResource.class); Connection connection = mock (Connection.class); when (singleXAConnection.getConnection ()) .thenReturn (connection); when (singleXAConnection.getXAResource ()) .thenReturn (singleXAResource); when (singleXADataSource.getXAConnection ()) .thenReturn (singleXAConnection); when (singleXADataSource.getResourceName ()) .thenReturn (datasourceName); when (singleXADataSource.getXaDataSource ()) .thenReturn (xaDataSource); Map result = new HashMap () Result.put (datasourceName, singleXADataSource); return result;} private Collection createResourceDataSources (final Class)