You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by lu...@apache.org on 2022/07/08 07:39:07 UTC

[shardingsphere] branch master updated: Support a Proxy instance using one TM. (#18911)

This is an automated email from the ASF dual-hosted git repository.

lujingshang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new b4dab0c45f8  Support a Proxy instance using one TM. (#18911)
b4dab0c45f8 is described below

commit b4dab0c45f8c7d30669322046036072b13673610
Author: Zhangcheng <fl...@outlook.com>
AuthorDate: Fri Jul 8 15:38:57 2022 +0800

     Support a Proxy instance using one TM. (#18911)
    
    * Support a Proxy instance uses one TM.
    
    * Fix no registered resource exception
    
    * Modify a proxy instance uses one TM
---
 .../rule/identifier/type/ResourceHeldRule.java     | 16 +++---
 .../driver/executor/AbstractBaseExecutorTest.java  |  2 +-
 .../datasource/ShardingSphereDataSourceTest.java   |  2 -
 .../transaction/ConnectionTransaction.java         |  2 +-
 .../transaction/rule/TransactionRule.java          | 61 ++++++++++++++--------
 .../transaction/ConnectionTransactionTest.java     |  2 -
 .../mode/manager/ContextManager.java               |  8 +--
 .../mode/metadata/MetaDataContexts.java            |  4 +-
 .../StandaloneContextManagerBuilderTextTest.java   |  2 -
 .../jdbc/datasource/JDBCBackendDataSource.java     |  2 +-
 .../transaction/JDBCBackendTransactionManager.java |  2 +-
 .../updatable/AlterTransactionRuleHandler.java     |  4 +-
 .../jdbc/connection/JDBCBackendConnectionTest.java | 10 +---
 .../jdbc/datasource/JDBCBackendDataSourceTest.java |  2 +-
 .../JDBCBackendTransactionManagerTest.java         |  4 +-
 .../TextProtocolBackendHandlerFactoryTest.java     |  2 +-
 .../updatable/AlterTransactionRuleHandlerTest.java |  3 --
 17 files changed, 61 insertions(+), 67 deletions(-)

diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ResourceHeldRule.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ResourceHeldRule.java
index ec6d039574b..61d48c2f0ac 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ResourceHeldRule.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ResourceHeldRule.java
@@ -20,8 +20,6 @@ package org.apache.shardingsphere.infra.rule.identifier.type;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
-import java.util.Map;
-
 /**
  * Resource held rule.
  * 
@@ -30,11 +28,11 @@ import java.util.Map;
 public interface ResourceHeldRule<T> extends ShardingSphereRule {
     
     /**
-     * Get resources.
+     * Get resource.
      * 
-     * @return got resources
+     * @return got resource
      */
-    Map<String, T> getResources();
+    T getResource();
     
     /**
      * Add resource.
@@ -44,14 +42,14 @@ public interface ResourceHeldRule<T> extends ShardingSphereRule {
     void addResource(ShardingSphereDatabase database);
     
     /**
-     * Close stale resource.
-     * 
+     * Close stale resource with database name.
+     *
      * @param databaseName database name
      */
     void closeStaleResource(String databaseName);
     
     /**
-     * Close stale resources.
+     * Close stale resource.
      */
-    void closeStaleResources();
+    void closeStaleResource();
 }
diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/executor/AbstractBaseExecutorTest.java b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/executor/AbstractBaseExecutorTest.java
index b5872620308..aaf43d07ac0 100644
--- a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/executor/AbstractBaseExecutorTest.java
+++ b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/executor/AbstractBaseExecutorTest.java
@@ -98,7 +98,7 @@ public abstract class AbstractBaseExecutorTest {
     
     private TransactionRule mockTransactionRule() {
         TransactionRule result = mock(TransactionRule.class);
-        when(result.getResources()).thenReturn(Collections.singletonMap(DefaultDatabase.LOGIC_NAME, new ShardingSphereTransactionManagerEngine()));
+        when(result.getResource()).thenReturn(new ShardingSphereTransactionManagerEngine());
         return result;
     }
     
diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java
index 4add4704d4d..c4ec0c9658a 100644
--- a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java
+++ b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java
@@ -59,7 +59,6 @@ public final class ShardingSphereDataSourceTest {
         ContextManager contextManager = getContextManager(actual);
         assertTrue(contextManager.getMetaDataContexts().getMetaData().getDatabases().containsKey(DefaultDatabase.LOGIC_NAME));
         TransactionRule transactionRule = contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(TransactionRule.class);
-        assertTrue(transactionRule.getResources().containsKey(DefaultDatabase.LOGIC_NAME));
         assertThat(contextManager.getInstanceContext().getInstance().getState().getCurrentState(), is(StateType.OK));
         assertTrue(contextManager.getDataSourceMap(DefaultDatabase.LOGIC_NAME).isEmpty());
     }
@@ -72,7 +71,6 @@ public final class ShardingSphereDataSourceTest {
         ContextManager contextManager = getContextManager(actual);
         assertTrue(contextManager.getMetaDataContexts().getMetaData().getDatabases().containsKey(DefaultDatabase.LOGIC_NAME));
         TransactionRule transactionRule = contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(TransactionRule.class);
-        assertTrue(transactionRule.getResources().containsKey(DefaultDatabase.LOGIC_NAME));
         assertThat(contextManager.getInstanceContext().getInstance().getState().getCurrentState(), is(StateType.OK));
         assertThat(contextManager.getDataSourceMap(DefaultDatabase.LOGIC_NAME).size(), is(1));
         assertThat(contextManager.getDataSourceMap(DefaultDatabase.LOGIC_NAME).get("ds").getConnection().getMetaData().getURL(), is("jdbc:mock://127.0.0.1/foo_ds"));
diff --git a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java
index 346b18d7615..a7bb4d30a05 100644
--- a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java
+++ b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java
@@ -47,7 +47,7 @@ public final class ConnectionTransaction {
     
     public ConnectionTransaction(final String databaseName, final TransactionType transactionType, final TransactionRule rule) {
         this.transactionType = transactionType;
-        transactionManager = rule.getResources().get(databaseName).getTransactionManager(transactionType);
+        transactionManager = rule.getResource().getTransactionManager(transactionType);
         TransactionTypeHolder.set(transactionType);
     }
     
diff --git a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java
index e15d2ce6da6..e469fd55283 100644
--- a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java
+++ b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java
@@ -19,15 +19,16 @@ package org.apache.shardingsphere.transaction.rule;
 
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResource;
 import org.apache.shardingsphere.infra.rule.identifier.scope.GlobalRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.ResourceHeldRule;
 import org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
 import org.apache.shardingsphere.transaction.core.TransactionType;
 
+import javax.sql.DataSource;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -50,7 +51,7 @@ public final class TransactionRule implements GlobalRule, ResourceHeldRule<Shard
     
     private final Map<String, ShardingSphereDatabase> databases;
     
-    private final Map<String, ShardingSphereTransactionManagerEngine> resources;
+    private volatile ShardingSphereTransactionManagerEngine resource;
     
     public TransactionRule(final TransactionRuleConfiguration ruleConfig, final Map<String, ShardingSphereDatabase> databases, final InstanceContext instanceContext) {
         configuration = ruleConfig;
@@ -58,21 +59,21 @@ public final class TransactionRule implements GlobalRule, ResourceHeldRule<Shard
         providerType = ruleConfig.getProviderType();
         props = ruleConfig.getProps();
         this.databases = databases;
-        resources = createTransactionManagerEngines(databases, instanceContext);
+        resource = createTransactionManagerEngine(databases);
     }
     
-    private Map<String, ShardingSphereTransactionManagerEngine> createTransactionManagerEngines(final Map<String, ShardingSphereDatabase> databases, final InstanceContext instanceContext) {
-        Map<String, ShardingSphereTransactionManagerEngine> result = new HashMap<>(databases.keySet().size(), 1);
-        for (Entry<String, ShardingSphereDatabase> entry : databases.entrySet()) {
-            result.put(entry.getKey(), createTransactionManagerEngine(entry.getValue()));
+    private synchronized ShardingSphereTransactionManagerEngine createTransactionManagerEngine(final Map<String, ShardingSphereDatabase> databases) {
+        if (databases.size() == 0) {
+            return new ShardingSphereTransactionManagerEngine();
         }
-        return result;
-    }
-    
-    private ShardingSphereTransactionManagerEngine createTransactionManagerEngine(final ShardingSphereDatabase database) {
         ShardingSphereTransactionManagerEngine result = new ShardingSphereTransactionManagerEngine();
-        ShardingSphereResource resource = database.getResource();
-        result.init(resource.getDatabaseType(), resource.getDataSources(), providerType);
+        Map<String, DataSource> dataSourceMap = new HashMap<>(databases.size());
+        DatabaseType databaseType = null;
+        for (Entry<String, ShardingSphereDatabase> entry : databases.entrySet()) {
+            dataSourceMap.putAll(entry.getValue().getResource().getDataSources());
+            databaseType = entry.getValue().getProtocolType();
+        }
+        result.init(databaseType, dataSourceMap, providerType);
         return result;
     }
     
@@ -82,23 +83,39 @@ public final class TransactionRule implements GlobalRule, ResourceHeldRule<Shard
         if (null == database) {
             return;
         }
-        ShardingSphereTransactionManagerEngine previousEngine = resources.put(database.getName(), createTransactionManagerEngine(database));
-        if (null != previousEngine) {
-            closeEngine(previousEngine);
-        }
+        databases.put(database.getName(), database);
+        rebuildEngine();
     }
     
     @Override
     public synchronized void closeStaleResource(final String databaseName) {
-        ShardingSphereTransactionManagerEngine engine = resources.remove(databaseName);
-        if (null != engine) {
-            closeEngine(engine);
+        if (!databases.containsKey(databaseName)) {
+            return;
         }
+        databases.remove(databaseName);
+        rebuildEngine();
     }
     
     @Override
-    public void closeStaleResources() {
-        resources.values().forEach(this::closeEngine);
+    public synchronized void closeStaleResource() {
+        databases.clear();
+        closeEngine();
+    }
+    
+    private void rebuildEngine() {
+        ShardingSphereTransactionManagerEngine previousEngine = resource;
+        if (null != previousEngine) {
+            closeEngine(previousEngine);
+        }
+        resource = createTransactionManagerEngine(databases);
+    }
+    
+    private void closeEngine() {
+        ShardingSphereTransactionManagerEngine engine = resource;
+        if (null != engine) {
+            closeEngine(engine);
+            resource = new ShardingSphereTransactionManagerEngine();
+        }
     }
     
     private void closeEngine(final ShardingSphereTransactionManagerEngine engine) {
diff --git a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/test/java/org/apache/shardingsphere/transaction/ConnectionTransactionTest.java b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/test/java/org/apache/shardingsphere/transaction/ConnectionTransactionTest.java
index 70bab540143..56550c5aeb0 100644
--- a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/test/java/org/apache/shardingsphere/transaction/ConnectionTransactionTest.java
+++ b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/test/java/org/apache/shardingsphere/transaction/ConnectionTransactionTest.java
@@ -72,13 +72,11 @@ public final class ConnectionTransactionTest {
     
     private TransactionRule getLocalTransactionRule() {
         TransactionRule result = new TransactionRule(new TransactionRuleConfiguration("LOCAL", null, new Properties()), Collections.emptyMap(), mock(InstanceContext.class));
-        result.getResources().put(DefaultDatabase.LOGIC_NAME, new ShardingSphereTransactionManagerEngine());
         return result;
     }
     
     private TransactionRule getXATransactionRule() {
         TransactionRule result = new TransactionRule(new TransactionRuleConfiguration("XA", "Atomikos", new Properties()), Collections.emptyMap(), mock(InstanceContext.class));
-        result.getResources().put(DefaultDatabase.LOGIC_NAME, new ShardingSphereTransactionManagerEngine());
         return result;
     }
 }
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index 90ea3c56726..5f150b0c798 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -294,9 +294,9 @@ public final class ContextManager implements AutoCloseable {
     public synchronized void alterRuleConfiguration(final String databaseName, final Collection<RuleConfiguration> ruleConfigs) {
         try {
             Collection<ResourceHeldRule> staleResourceHeldRules = getStaleResourceHeldRules(databaseName);
+            staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResource);
             metaDataContexts = createMetaDataContexts(databaseName, null, ruleConfigs);
             persistMetaData(metaDataContexts);
-            staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResources);
         } catch (final SQLException ex) {
             log.error("Alter database: {} rule configurations failed", databaseName, ex);
         }
@@ -312,10 +312,10 @@ public final class ContextManager implements AutoCloseable {
     public synchronized void alterDataSourceConfiguration(final String databaseName, final Map<String, DataSourceProperties> dataSourcePropsMap) {
         try {
             Collection<ResourceHeldRule> staleResourceHeldRules = getStaleResourceHeldRules(databaseName);
+            staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResource);
             SwitchingResource switchingResource = new ResourceSwitchManager().create(metaDataContexts.getMetaData().getDatabases().get(databaseName).getResource(), dataSourcePropsMap);
             metaDataContexts = createMetaDataContexts(databaseName, switchingResource, null);
             persistMetaData(metaDataContexts);
-            staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResources);
             switchingResource.closeStaleDataSources();
         } catch (final SQLException ex) {
             log.error("Alter database: {} data source configuration failed", databaseName, ex);
@@ -334,10 +334,10 @@ public final class ContextManager implements AutoCloseable {
                                                                  final Map<String, DataSourceProperties> dataSourcePropsMap, final Collection<RuleConfiguration> ruleConfigs) {
         try {
             Collection<ResourceHeldRule> staleResourceHeldRules = getStaleResourceHeldRules(databaseName);
+            staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResource);
             SwitchingResource switchingResource = new ResourceSwitchManager().create(metaDataContexts.getMetaData().getDatabases().get(databaseName).getResource(), dataSourcePropsMap);
             metaDataContexts = createMetaDataContexts(databaseName, switchingResource, ruleConfigs);
             persistMetaData(metaDataContexts);
-            staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResources);
             switchingResource.closeStaleDataSources();
         } catch (SQLException ex) {
             log.error("Alter database: {} data source and rule configuration failed", databaseName, ex);
@@ -390,12 +390,12 @@ public final class ContextManager implements AutoCloseable {
             return;
         }
         Collection<ResourceHeldRule> staleResourceHeldRules = metaDataContexts.getMetaData().getGlobalRuleMetaData().findRules(ResourceHeldRule.class);
+        staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResource);
         ShardingSphereRuleMetaData toBeChangedGlobalRuleMetaData = new ShardingSphereRuleMetaData(
                 GlobalRulesBuilder.buildRules(ruleConfigs, metaDataContexts.getMetaData().getDatabases(), instanceContext));
         ShardingSphereMetaData toBeChangedMetaData = new ShardingSphereMetaData(
                 metaDataContexts.getMetaData().getDatabases(), toBeChangedGlobalRuleMetaData, metaDataContexts.getMetaData().getProps());
         metaDataContexts = newMetaDataContexts(toBeChangedMetaData, metaDataContexts.getOptimizerContext());
-        staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResources);
     }
     
     /**
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java
index 6eb899bf66e..b83edfd4528 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java
@@ -53,7 +53,7 @@ public final class MetaDataContexts implements AutoCloseable {
         if (null != persistService) {
             persistService.getRepository().close();
         }
-        metaData.getGlobalRuleMetaData().findRules(ResourceHeldRule.class).forEach(ResourceHeldRule::closeStaleResources);
-        metaData.getDatabases().values().forEach(each -> each.getRuleMetaData().findRules(ResourceHeldRule.class).forEach(ResourceHeldRule::closeStaleResources));
+        metaData.getGlobalRuleMetaData().findRules(ResourceHeldRule.class).forEach(ResourceHeldRule::closeStaleResource);
+        metaData.getDatabases().values().forEach(each -> each.getRuleMetaData().findRules(ResourceHeldRule.class).forEach(ResourceHeldRule::closeStaleResource));
     }
 }
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-standalone-mode/shardingsphere-standalone-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilderTextTest.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-standalone-mode/shardingsphere-standalone-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilderTextTest.java
index 505bf9bbde6..2911ac563bb 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-standalone-mode/shardingsphere-standalone-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilderTextTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-standalone-mode/shardingsphere-standalone-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilderTextTest.java
@@ -29,7 +29,6 @@ import org.apache.shardingsphere.mode.metadata.persist.node.DatabaseMetaDataNode
 import org.apache.shardingsphere.mode.metadata.persist.node.GlobalNode;
 import org.apache.shardingsphere.mode.persist.PersistRepository;
 import org.apache.shardingsphere.test.mock.MockedDataSource;
-import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.Test;
 
 import java.sql.SQLException;
@@ -54,7 +53,6 @@ public final class StandaloneContextManagerBuilderTextTest {
         assertNotNull(repository.get(GlobalNode.getGlobalRuleNode()));
         assertNotNull(repository.get(DatabaseMetaDataNode.getMetaDataDataSourcePath("foo_db", "0")));
         assertNotNull(repository.get(DatabaseMetaDataNode.getRulePath("foo_db", "0")));
-        assertTrue(actual.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(TransactionRule.class).getResources().containsKey("foo_db"));
     }
     
     private ContextManagerBuilderParameter createContextManagerBuilderParameter() {
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSource.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSource.java
index 73ba617c372..87c0ce1e203 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSource.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSource.java
@@ -105,7 +105,7 @@ public final class JDBCBackendDataSource implements BackendDataSource {
     
     private Connection createConnection(final String databaseName, final String dataSourceName, final DataSource dataSource, final TransactionType transactionType) throws SQLException {
         TransactionRule transactionRule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(TransactionRule.class);
-        ShardingSphereTransactionManager transactionManager = transactionRule.getResources().get(databaseName).getTransactionManager(transactionType);
+        ShardingSphereTransactionManager transactionManager = transactionRule.getResource().getTransactionManager(transactionType);
         Connection result = isInTransaction(transactionManager) ? transactionManager.getConnection(dataSourceName) : dataSource.getConnection();
         if (dataSourceName.contains(".")) {
             String catalog = dataSourceName.split("\\.")[1];
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManager.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManager.java
index 355893b54e5..a558b125c25 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManager.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManager.java
@@ -51,7 +51,7 @@ public final class JDBCBackendTransactionManager implements TransactionManager<V
         transactionType = connection.getConnectionSession().getTransactionStatus().getTransactionType();
         localTransactionManager = new LocalTransactionManager(backendConnection);
         TransactionRule transactionRule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(TransactionRule.class);
-        ShardingSphereTransactionManagerEngine engine = transactionRule.getResources().get(connection.getConnectionSession().getDatabaseName());
+        ShardingSphereTransactionManagerEngine engine = transactionRule.getResource();
         shardingSphereTransactionManager = null == engine ? null : engine.getTransactionManager(transactionType);
     }
     
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandler.java
index 9d8c6fb9752..1ca1ff32aa7 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandler.java
@@ -44,12 +44,10 @@ public final class AlterTransactionRuleHandler extends UpdatableRALBackendHandle
     private void replaceNewRule(final ContextManager contextManager) {
         TransactionRuleConfiguration toBeAlteredRuleConfig = createToBeAlteredRuleConfiguration();
         Collection<ShardingSphereRule> globalRules = contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getRules();
+        globalRules.stream().filter(each -> each instanceof TransactionRule).forEach(each -> ((TransactionRule) each).closeStaleResource());
         globalRules.removeIf(each -> each instanceof TransactionRule);
         Map<String, ShardingSphereDatabase> databases = contextManager.getMetaDataContexts().getMetaData().getDatabases();
         TransactionRule transactionRule = new TransactionRule(toBeAlteredRuleConfig, databases, contextManager.getInstanceContext());
-        for (String each : transactionRule.getResources().keySet()) {
-            transactionRule.addResource(databases.get(each));
-        }
         globalRules.add(transactionRule);
     }
     
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/JDBCBackendConnectionTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/JDBCBackendConnectionTest.java
index 914fa425918..e88ad2039c9 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/JDBCBackendConnectionTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/JDBCBackendConnectionTest.java
@@ -124,19 +124,11 @@ public final class JDBCBackendConnectionTest extends ProxyContextRestorer {
     private ShardingSphereRuleMetaData mockGlobalRuleMetaData() {
         ShardingSphereRuleMetaData result = mock(ShardingSphereRuleMetaData.class);
         TransactionRule transactionRule = mock(TransactionRule.class);
-        when(transactionRule.getResources()).thenReturn(createTransactionManagerEngines());
+        when(transactionRule.getResource()).thenReturn(new ShardingSphereTransactionManagerEngine());
         when(result.getSingleRule(TransactionRule.class)).thenReturn(transactionRule);
         return result;
     }
     
-    private Map<String, ShardingSphereTransactionManagerEngine> createTransactionManagerEngines() {
-        Map<String, ShardingSphereTransactionManagerEngine> result = new HashMap<>(10, 1);
-        for (int i = 0; i < 10; i++) {
-            result.put(String.format(SCHEMA_PATTERN, i), new ShardingSphereTransactionManagerEngine());
-        }
-        return result;
-    }
-    
     private void setBackendDataSource() throws ReflectiveOperationException {
         Field field = ProxyContext.getInstance().getClass().getDeclaredField("backendDataSource");
         field.setAccessible(true);
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSourceTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSourceTest.java
index 0f99cd101ee..296d33c42c1 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSourceTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/JDBCBackendDataSourceTest.java
@@ -84,7 +84,7 @@ public final class JDBCBackendDataSourceTest extends ProxyContextRestorer {
     private ShardingSphereRuleMetaData mockGlobalRuleMetaData() {
         ShardingSphereRuleMetaData result = mock(ShardingSphereRuleMetaData.class);
         TransactionRule transactionRule = mock(TransactionRule.class);
-        when(transactionRule.getResources()).thenReturn(Collections.singletonMap("schema", mock(ShardingSphereTransactionManagerEngine.class)));
+        when(transactionRule.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
         when(result.getSingleRule(TransactionRule.class)).thenReturn(transactionRule);
         return result;
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManagerTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManagerTest.java
index 6714c6a9164..389b872a2dd 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManagerTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/transaction/JDBCBackendTransactionManagerTest.java
@@ -37,7 +37,6 @@ import org.mockito.junit.MockitoJUnitRunner;
 
 import java.lang.reflect.Field;
 import java.sql.SQLException;
-import java.util.Collections;
 
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
@@ -68,7 +67,6 @@ public final class JDBCBackendTransactionManagerTest extends ProxyContextRestore
     @Before
     public void setUp() {
         setTransactionContexts();
-        when(connectionSession.getDatabaseName()).thenReturn("db");
         when(connectionSession.getTransactionStatus()).thenReturn(transactionStatus);
         when(backendConnection.getConnectionSession()).thenReturn(connectionSession);
     }
@@ -85,7 +83,7 @@ public final class JDBCBackendTransactionManagerTest extends ProxyContextRestore
         TransactionRule transactionRule = mock(TransactionRule.class);
         ShardingSphereTransactionManagerEngine transactionManagerEngine = mock(ShardingSphereTransactionManagerEngine.class);
         when(transactionManagerEngine.getTransactionManager(TransactionType.XA)).thenReturn(shardingSphereTransactionManager);
-        when(transactionRule.getResources()).thenReturn(Collections.singletonMap("db", transactionManagerEngine));
+        when(transactionRule.getResource()).thenReturn(transactionManagerEngine);
         when(result.getSingleRule(TransactionRule.class)).thenReturn(transactionRule);
         return result;
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/TextProtocolBackendHandlerFactoryTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/TextProtocolBackendHandlerFactoryTest.java
index 73e3c561e64..d2a11166c9d 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/TextProtocolBackendHandlerFactoryTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/TextProtocolBackendHandlerFactoryTest.java
@@ -106,7 +106,7 @@ public final class TextProtocolBackendHandlerFactoryTest extends ProxyContextRes
     private void mockGlobalRuleMetaData(final MetaDataContexts metaDataContexts) {
         ShardingSphereRuleMetaData globalRuleMetaData = mock(ShardingSphereRuleMetaData.class);
         TransactionRule transactionRule = mock(TransactionRule.class);
-        when(transactionRule.getResources()).thenReturn(Collections.singletonMap("schema", new ShardingSphereTransactionManagerEngine()));
+        when(transactionRule.getResource()).thenReturn(new ShardingSphereTransactionManagerEngine());
         when(globalRuleMetaData.getSingleRule(TransactionRule.class)).thenReturn(transactionRule);
         when(metaDataContexts.getMetaData().getGlobalRuleMetaData()).thenReturn(globalRuleMetaData);
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandlerTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandlerTest.java
index f87e52ca775..664c7ef93c3 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandlerTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/AlterTransactionRuleHandlerTest.java
@@ -21,7 +21,6 @@ import com.atomikos.jdbc.AtomikosDataSourceBean;
 import org.apache.shardingsphere.distsql.parser.segment.TransactionProviderSegment;
 import org.apache.shardingsphere.distsql.parser.statement.ral.common.updatable.AlterTransactionRuleStatement;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
-import org.apache.shardingsphere.infra.database.DefaultDatabase;
 import org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContext;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
@@ -33,7 +32,6 @@ import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import org.apache.shardingsphere.proxy.backend.util.ProxyContextRestorer;
-import org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
 import org.apache.shardingsphere.transaction.core.TransactionType;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
@@ -74,7 +72,6 @@ public final class AlterTransactionRuleHandlerTest extends ProxyContextRestorer
     
     private TransactionRule createTransactionRule() {
         TransactionRule result = new TransactionRule(new TransactionRuleConfiguration("LOCAL", null, new Properties()), Collections.emptyMap(), mock(InstanceContext.class));
-        result.getResources().put(DefaultDatabase.LOGIC_NAME, new ShardingSphereTransactionManagerEngine());
         return result;
     }