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

wuweijie 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 bd2977dce43 Remove ResourceHeldRuleAttribute (#30520)
bd2977dce43 is described below

commit bd2977dce4396c3db83d25926b3e2e3e7387ad1f
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Mar 17 23:44:10 2024 +0800

    Remove ResourceHeldRuleAttribute (#30520)
    
    * Refactor ResourceHeldRuleAttribute
    
    * Remove ResourceHeldRuleAttribute
    
    * Remove ResourceHeldRuleAttribute
---
 .../infra/metadata/ShardingSphereMetaData.java     |  15 ++-
 .../resoure/ResourceHeldRuleAttribute.java         |  53 ---------
 .../infra/rule/scope/GlobalRule.java               |  11 ++
 .../infra/metadata/ShardingSphereMetaDataTest.java |  22 +---
 .../driver/jdbc/adapter/ConnectionAdapterTest.java |  10 +-
 .../DriverDatabaseConnectionManagerTest.java       |  10 +-
 .../UnsupportedOperationConnectionTest.java        |  13 +--
 .../driver/state/DriverStateContextTest.java       |   7 +-
 .../driver/state/ok/OKDriverStateTest.java         |  11 +-
 .../transaction/ConnectionTransaction.java         |   3 +-
 .../rule/TransactionResourceHeldRuleAttribute.java | 128 ---------------------
 .../transaction/rule/TransactionRule.java          |  74 +++++++++++-
 .../transaction/rule/TransactionRuleTest.java      |  49 ++------
 .../rule/builder/TransactionRuleBuilderTest.java   |   8 +-
 .../context/ConfigurationContextManager.java       |  36 +++---
 .../mode/metadata/MetaDataContexts.java            |  20 +++-
 .../mode/metadata/MetaDataContextsFactoryTest.java |   1 +
 .../NewStandaloneModeContextManager.java           |  10 +-
 .../standalone/StandaloneModeContextManager.java   |  10 +-
 .../jdbc/datasource/JDBCBackendDataSource.java     |   5 +-
 .../transaction/BackendTransactionManager.java     |   3 +-
 .../jdbc/datasource/JDBCBackendDataSourceTest.java |  20 +---
 .../transaction/BackendTransactionManagerTest.java |   9 +-
 .../TransactionBackendHandlerFactoryTest.java      |  14 +--
 .../transaction/TransactionBackendHandlerTest.java |  10 +-
 .../backend/session/ConnectionSessionTest.java     |  12 +-
 26 files changed, 181 insertions(+), 383 deletions(-)

diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaData.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaData.java
index f77ee6cfcd5..46c5b927469 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaData.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaData.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.infra.metadata;
 
 import lombok.Getter;
+import lombok.SneakyThrows;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import 
org.apache.shardingsphere.infra.config.props.temporary.TemporaryConfigurationProperties;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
@@ -25,8 +26,9 @@ import 
org.apache.shardingsphere.infra.datasource.pool.destroyer.DataSourcePoolD
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import 
org.apache.shardingsphere.infra.rule.attribute.datasource.StaticDataSourceRuleAttribute;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
+import org.apache.shardingsphere.infra.rule.scope.GlobalRule;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -95,7 +97,7 @@ public final class ShardingSphereMetaData {
     public void addDatabase(final String databaseName, final DatabaseType 
protocolType, final ConfigurationProperties props) {
         ShardingSphereDatabase database = 
ShardingSphereDatabase.create(databaseName, protocolType, props);
         databases.put(database.getName().toLowerCase(), database);
-        
globalRuleMetaData.getAttributes(ResourceHeldRuleAttribute.class).forEach(each 
-> each.addResource(database));
+        globalRuleMetaData.getRules().forEach(each -> ((GlobalRule) 
each).refresh(databases));
     }
     
     /**
@@ -107,9 +109,14 @@ public final class ShardingSphereMetaData {
         cleanResources(databases.remove(databaseName.toLowerCase()));
     }
     
+    @SneakyThrows(Exception.class)
     private void cleanResources(final ShardingSphereDatabase database) {
-        
globalRuleMetaData.getAttributes(ResourceHeldRuleAttribute.class).forEach(each 
-> each.dropResource(database.getName()));
-        
database.getRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class).forEach(each
 -> each.dropResource(database.getName()));
+        globalRuleMetaData.getRules().forEach(each -> ((GlobalRule) 
each).refresh(databases));
+        for (ShardingSphereRule each : database.getRuleMetaData().getRules()) {
+            if (each instanceof AutoCloseable) {
+                ((AutoCloseable) each).close();
+            }
+        }
         
database.getRuleMetaData().getAttributes(StaticDataSourceRuleAttribute.class).forEach(StaticDataSourceRuleAttribute::cleanStorageNodeDataSources);
         Optional.ofNullable(database.getResourceMetaData())
                 .ifPresent(optional -> 
optional.getStorageUnits().values().forEach(each -> new 
DataSourcePoolDestroyer(each.getDataSource()).asyncDestroy()));
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/attribute/resoure/ResourceHeldRuleAttribute.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/attribute/resoure/ResourceHeldRuleAttribute.java
deleted file mode 100644
index c636c123bd8..00000000000
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/attribute/resoure/ResourceHeldRuleAttribute.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.infra.rule.attribute.resoure;
-
-import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttribute;
-
-/**
- * Resource held rule attribute.
- * 
- * @param <T> type of resource
- */
-public interface ResourceHeldRuleAttribute<T> extends RuleAttribute, 
AutoCloseable {
-    
-    /**
-     * Get resource.
-     * 
-     * @return got resource
-     */
-    T getResource();
-    
-    /**
-     * Add resource.
-     *
-     * @param database database
-     */
-    void addResource(ShardingSphereDatabase database);
-    
-    /**
-     * Drop resource.
-     *
-     * @param databaseName database name
-     */
-    void dropResource(String databaseName);
-    
-    @Override
-    void close();
-}
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/scope/GlobalRule.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/scope/GlobalRule.java
index fbe266c2144..f18df6a6cd5 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/scope/GlobalRule.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/scope/GlobalRule.java
@@ -17,10 +17,21 @@
 
 package org.apache.shardingsphere.infra.rule.scope;
 
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
+import java.util.Map;
+
 /**
  * Global rule.
  */
 public interface GlobalRule extends ShardingSphereRule {
+    
+    /**
+     * Refresh rule when databases changed.
+     * 
+     * @param databases changed databases
+     */
+    default void refresh(final Map<String, ShardingSphereDatabase> databases) {
+    }
 }
diff --git 
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaDataTest.java
 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaDataTest.java
index d6389ab2c72..97f7c6e7926 100644
--- 
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaDataTest.java
+++ 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/ShardingSphereMetaDataTest.java
@@ -26,8 +26,8 @@ import 
org.apache.shardingsphere.infra.metadata.database.resource.node.StorageNo
 import 
org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
+import org.apache.shardingsphere.infra.rule.scope.GlobalRule;
 import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource;
 import org.apache.shardingsphere.test.mock.AutoMockExtension;
 import org.apache.shardingsphere.test.mock.StaticMockSettings;
@@ -59,9 +59,7 @@ class ShardingSphereMetaDataTest {
     
     @Test
     void assertAddDatabase() {
-        ResourceHeldRuleAttribute<?> globalResourceHeldRuleAttribute = 
mock(ResourceHeldRuleAttribute.class);
-        ShardingSphereRule globalRule = mock(ShardingSphereRule.class);
-        when(globalRule.getAttributes()).thenReturn(new 
RuleAttributes(globalResourceHeldRuleAttribute));
+        GlobalRule globalRule = mock(GlobalRule.class);
         ShardingSphereDatabase database = 
mockDatabase(mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), new 
MockedDataSource(), globalRule);
         DatabaseType databaseType = mock(DatabaseType.class);
         ConfigurationProperties configProps = new ConfigurationProperties(new 
Properties());
@@ -70,34 +68,28 @@ class ShardingSphereMetaDataTest {
         ShardingSphereMetaData metaData = new 
ShardingSphereMetaData(databases, mock(ResourceMetaData.class), new 
RuleMetaData(Collections.singleton(globalRule)), configProps);
         metaData.addDatabase("foo_db", databaseType, configProps);
         assertThat(metaData.getDatabases(), is(databases));
-        verify(globalResourceHeldRuleAttribute).addResource(database);
+        verify(globalRule).refresh(databases);
     }
     
     @Test
     void assertDropDatabase() {
         ResourceMetaData resourceMetaData = mock(ResourceMetaData.class, 
RETURNS_DEEP_STUBS);
+        GlobalRule globalRule = mock(GlobalRule.class);
         MockedDataSource dataSource = new MockedDataSource();
-        ResourceHeldRuleAttribute<?> databaseResourceHeldRuleAttribute = 
mock(ResourceHeldRuleAttribute.class, RETURNS_DEEP_STUBS);
-        ResourceHeldRuleAttribute<?> globalResourceHeldRuleAttribute = 
mock(ResourceHeldRuleAttribute.class);
         ShardingSphereRule databaseRule = mock(ShardingSphereRule.class);
-        when(databaseRule.getAttributes()).thenReturn(new 
RuleAttributes(databaseResourceHeldRuleAttribute));
-        ShardingSphereRule globalRule = mock(ShardingSphereRule.class);
-        when(globalRule.getAttributes()).thenReturn(new 
RuleAttributes(globalResourceHeldRuleAttribute));
+        when(databaseRule.getAttributes()).thenReturn(new RuleAttributes());
         ShardingSphereMetaData metaData = new ShardingSphereMetaData(new 
HashMap<>(Collections.singletonMap("foo_db", mockDatabase(resourceMetaData, 
dataSource, databaseRule))),
                 mock(ResourceMetaData.class), new 
RuleMetaData(Collections.singleton(globalRule)), new 
ConfigurationProperties(new Properties()));
         metaData.dropDatabase("foo_db");
         assertTrue(metaData.getDatabases().isEmpty());
         Awaitility.await().pollDelay(10L, 
TimeUnit.MILLISECONDS).until(dataSource::isClosed);
         assertTrue(dataSource.isClosed());
-        verify(databaseResourceHeldRuleAttribute).dropResource("foo_db");
-        verify(globalResourceHeldRuleAttribute).dropResource("foo_db");
+        verify(globalRule).refresh(metaData.getDatabases());
     }
     
     @Test
     void assertContainsDatabase() {
-        ResourceHeldRuleAttribute<?> globalResourceHeldRuleAttribute = 
mock(ResourceHeldRuleAttribute.class);
         ShardingSphereRule globalRule = mock(ShardingSphereRule.class);
-        when(globalRule.getAttributes()).thenReturn(new 
RuleAttributes(globalResourceHeldRuleAttribute));
         ShardingSphereDatabase database = 
mockDatabase(mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), new 
MockedDataSource(), globalRule);
         Map<String, ShardingSphereDatabase> databases = new 
HashMap<>(Collections.singletonMap("foo_db", database));
         ConfigurationProperties configProps = new ConfigurationProperties(new 
Properties());
@@ -107,9 +99,7 @@ class ShardingSphereMetaDataTest {
     
     @Test
     void assertGetDatabase() {
-        ResourceHeldRuleAttribute<?> globalResourceHeldRuleAttribute = 
mock(ResourceHeldRuleAttribute.class);
         ShardingSphereRule globalRule = mock(ShardingSphereRule.class);
-        when(globalRule.getAttributes()).thenReturn(new 
RuleAttributes(globalResourceHeldRuleAttribute));
         ShardingSphereDatabase database = 
mockDatabase(mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), new 
MockedDataSource(), globalRule);
         Map<String, ShardingSphereDatabase> databases = new 
HashMap<>(Collections.singletonMap("foo_db", database));
         ConfigurationProperties configProps = new ConfigurationProperties(new 
Properties());
diff --git 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ConnectionAdapterTest.java
 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ConnectionAdapterTest.java
index 923c9d4b8be..69c972de9b3 100644
--- 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ConnectionAdapterTest.java
+++ 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ConnectionAdapterTest.java
@@ -20,12 +20,9 @@ package org.apache.shardingsphere.driver.jdbc.adapter;
 import 
org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection;
 import org.apache.shardingsphere.infra.database.core.DefaultDatabase;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.traffic.rule.TrafficRule;
 import 
org.apache.shardingsphere.traffic.rule.builder.DefaultTrafficRuleConfigurationBuilder;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.jupiter.api.Test;
 
@@ -99,15 +96,10 @@ class ConnectionAdapterTest {
         }
     }
     
-    @SuppressWarnings("unchecked")
     private Connection createConnectionAdaptor() {
         ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
         
when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(
-                new RuleMetaData(Arrays.asList(transactionRule, new 
TrafficRule(new DefaultTrafficRuleConfigurationBuilder().build()))));
+                new RuleMetaData(Arrays.asList(mock(TransactionRule.class, 
RETURNS_DEEP_STUBS), new TrafficRule(new 
DefaultTrafficRuleConfigurationBuilder().build()))));
         return new ShardingSphereConnection(DefaultDatabase.LOGIC_NAME, 
contextManager);
     }
 }
diff --git 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/core/connection/DriverDatabaseConnectionManagerTest.java
 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/core/connection/DriverDatabaseConnectionManagerTest.java
index 1b4ce67dddc..51a97656508 100644
--- 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/core/connection/DriverDatabaseConnectionManagerTest.java
+++ 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/core/connection/DriverDatabaseConnectionManagerTest.java
@@ -27,15 +27,12 @@ import 
org.apache.shardingsphere.infra.instance.metadata.proxy.ProxyInstanceMeta
 import 
org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.metadata.persist.MetaDataPersistService;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource;
 import org.apache.shardingsphere.test.mock.AutoMockExtension;
 import org.apache.shardingsphere.test.mock.StaticMockSettings;
 import org.apache.shardingsphere.traffic.rule.TrafficRule;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -76,19 +73,14 @@ class DriverDatabaseConnectionManagerTest {
         databaseConnectionManager = new 
DriverDatabaseConnectionManager(DefaultDatabase.LOGIC_NAME, 
mockContextManager());
     }
     
-    @SuppressWarnings("unchecked")
     private ContextManager mockContextManager() throws SQLException {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
         Map<String, StorageUnit> storageUnits = mockStorageUnits();
         
when(result.getStorageUnits(DefaultDatabase.LOGIC_NAME)).thenReturn(storageUnits);
         MetaDataPersistService persistService = mockMetaDataPersistService();
         
when(result.getMetaDataContexts().getPersistService()).thenReturn(persistService);
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
         
when(result.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(
-                new RuleMetaData(Arrays.asList(transactionRule, 
mock(TrafficRule.class, RETURNS_DEEP_STUBS))));
+                new RuleMetaData(Arrays.asList(mock(TransactionRule.class, 
RETURNS_DEEP_STUBS), mock(TrafficRule.class, RETURNS_DEEP_STUBS))));
         
when(result.getInstanceContext().getAllClusterInstances(InstanceType.PROXY, 
Arrays.asList("OLTP", "OLAP"))).thenReturn(
                 Collections.singletonMap("foo_id", new 
ProxyInstanceMetaData("foo_id", "127.0.0.1@3307", "foo_version")));
         Map<String, DataSource> trafficDataSourceMap = 
mockTrafficDataSourceMap();
diff --git 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
index 268d50fab9d..cb742ff8168 100644
--- 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
+++ 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
@@ -19,13 +19,10 @@ package org.apache.shardingsphere.driver.jdbc.unsupported;
 
 import 
org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection;
 import org.apache.shardingsphere.infra.database.core.DefaultDatabase;
-import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import 
org.apache.shardingsphere.infra.exception.core.external.sql.type.generic.UnsupportedSQLOperationException;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.traffic.rule.TrafficRule;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.jupiter.api.Test;
 
@@ -42,14 +39,10 @@ class UnsupportedOperationConnectionTest {
     
     private final ShardingSphereConnection shardingSphereConnection;
     
-    @SuppressWarnings("unchecked")
     UnsupportedOperationConnectionTest() {
         ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
-        
when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Arrays.asList(transactionRule, mock(TrafficRule.class))));
+        
when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(
+                new RuleMetaData(Arrays.asList(mock(TransactionRule.class, 
RETURNS_DEEP_STUBS), mock(TrafficRule.class))));
         shardingSphereConnection = new 
ShardingSphereConnection(DefaultDatabase.LOGIC_NAME, contextManager);
     }
     
diff --git 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java
 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java
index 741c1664c92..df7af792391 100644
--- 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java
+++ 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java
@@ -25,8 +25,6 @@ import 
org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.infra.state.cluster.ClusterStateContext;
 import org.apache.shardingsphere.infra.state.instance.InstanceStateContext;
@@ -60,14 +58,11 @@ class DriverStateContextTest {
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private ContextManager contextManager;
     
-    @SuppressWarnings("unchecked")
     @BeforeEach
     void setUp() {
         Map<String, ShardingSphereDatabase> databases = mockDatabases();
         TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
+        
when(transactionRule.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
         TrafficRule trafficRule = mock(TrafficRule.class);
         RuleMetaData globalRuleMetaData = new 
RuleMetaData(Arrays.asList(transactionRule, trafficRule));
         MetaDataContexts metaDataContexts = new MetaDataContexts(
diff --git 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/state/ok/OKDriverStateTest.java
 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/state/ok/OKDriverStateTest.java
index 4f817db2a18..3092f340416 100644
--- 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/state/ok/OKDriverStateTest.java
+++ 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/state/ok/OKDriverStateTest.java
@@ -20,11 +20,8 @@ package org.apache.shardingsphere.driver.state.ok;
 import 
org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection;
 import org.apache.shardingsphere.infra.database.core.DefaultDatabase;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.traffic.rule.TrafficRule;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.jupiter.api.Test;
 
@@ -39,15 +36,11 @@ import static org.mockito.Mockito.when;
 
 class OKDriverStateTest {
     
-    @SuppressWarnings("unchecked")
     @Test
     void assertGetConnection() {
         ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
-        
when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Arrays.asList(transactionRule, mock(TrafficRule.class))));
+        
when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(
+                new RuleMetaData(Arrays.asList(mock(TransactionRule.class, 
RETURNS_DEEP_STUBS), mock(TrafficRule.class))));
         Connection actual = new 
OKDriverState().getConnection(DefaultDatabase.LOGIC_NAME, contextManager);
         assertThat(actual, instanceOf(ShardingSphereConnection.class));
     }
diff --git 
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java
 
b/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java
index bda76f0cb58..f0d2e4fdd5e 100644
--- 
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java
+++ 
b/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionTransaction.java
@@ -19,7 +19,6 @@ package org.apache.shardingsphere.transaction;
 
 import lombok.Getter;
 import lombok.Setter;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import 
org.apache.shardingsphere.infra.session.connection.transaction.TransactionConnectionContext;
 import org.apache.shardingsphere.transaction.api.TransactionType;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
@@ -49,7 +48,7 @@ public final class ConnectionTransaction {
     
     public ConnectionTransaction(final TransactionType transactionType, final 
TransactionRule rule) {
         this.transactionType = transactionType;
-        transactionManager = ((ShardingSphereTransactionManagerEngine) 
rule.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource()).getTransactionManager(transactionType);
+        transactionManager = 
rule.getResource().getTransactionManager(transactionType);
     }
     
     /**
diff --git 
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionResourceHeldRuleAttribute.java
 
b/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionResourceHeldRuleAttribute.java
deleted file mode 100644
index 03f9babb610..00000000000
--- 
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionResourceHeldRuleAttribute.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.transaction.rule;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
-import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
-import org.apache.shardingsphere.transaction.api.TransactionType;
-
-import javax.sql.DataSource;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Transaction resource held rule attribute.
- */
-@Slf4j
-public final class TransactionResourceHeldRuleAttribute implements 
ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> {
-    
-    private final TransactionType defaultType;
-    
-    private final String providerType;
-    
-    private final Map<String, ShardingSphereDatabase> databases;
-    
-    private final AtomicReference<ShardingSphereTransactionManagerEngine> 
resource;
-    
-    public TransactionResourceHeldRuleAttribute(final TransactionType 
defaultType, final String providerType, final Map<String, 
ShardingSphereDatabase> databases) {
-        this.defaultType = defaultType;
-        this.providerType = providerType;
-        this.databases = databases;
-        resource = new 
AtomicReference<>(createTransactionManagerEngine(this.databases));
-    }
-    
-    @Override
-    public ShardingSphereTransactionManagerEngine getResource() {
-        return resource.get();
-    }
-    
-    @Override
-    public synchronized void addResource(final ShardingSphereDatabase 
database) {
-        // TODO process null when for information_schema
-        if (null == database) {
-            return;
-        }
-        databases.put(database.getName(), database);
-        rebuildEngine();
-    }
-    
-    @Override
-    public synchronized void dropResource(final String databaseName) {
-        if (!databases.containsKey(databaseName.toLowerCase())) {
-            return;
-        }
-        databases.remove(databaseName);
-        rebuildEngine();
-    }
-    
-    @Override
-    public synchronized void close() {
-        databases.clear();
-        closeEngine();
-    }
-    
-    private void rebuildEngine() {
-        ShardingSphereTransactionManagerEngine previousEngine = resource.get();
-        if (null != previousEngine) {
-            closeEngine(previousEngine);
-        }
-        resource.set(createTransactionManagerEngine(databases));
-    }
-    
-    private synchronized ShardingSphereTransactionManagerEngine 
createTransactionManagerEngine(final Map<String, ShardingSphereDatabase> 
databases) {
-        if (databases.isEmpty()) {
-            return new ShardingSphereTransactionManagerEngine(defaultType);
-        }
-        Map<String, DataSource> dataSourceMap = new 
LinkedHashMap<>(databases.size(), 1F);
-        Map<String, DatabaseType> databaseTypes = new 
LinkedHashMap<>(databases.size(), 1F);
-        for (Entry<String, ShardingSphereDatabase> entry : 
databases.entrySet()) {
-            ShardingSphereDatabase database = entry.getValue();
-            database.getResourceMetaData().getStorageUnits().forEach((key, 
value) -> dataSourceMap.put(database.getName() + "." + key, 
value.getDataSource()));
-            database.getResourceMetaData().getStorageUnits().forEach((key, 
value) -> databaseTypes.put(database.getName() + "." + key, 
value.getStorageType()));
-        }
-        if (dataSourceMap.isEmpty()) {
-            return new ShardingSphereTransactionManagerEngine(defaultType);
-        }
-        ShardingSphereTransactionManagerEngine result = new 
ShardingSphereTransactionManagerEngine(defaultType);
-        result.init(databaseTypes, dataSourceMap, providerType);
-        return result;
-    }
-    
-    private void closeEngine() {
-        ShardingSphereTransactionManagerEngine engine = resource.get();
-        if (null != engine) {
-            closeEngine(engine);
-            resource.set(new 
ShardingSphereTransactionManagerEngine(defaultType));
-        }
-    }
-    
-    private void closeEngine(final ShardingSphereTransactionManagerEngine 
engine) {
-        try {
-            engine.close();
-            // CHECKSTYLE:OFF
-        } catch (final RuntimeException ex) {
-            // CHECKSTYLE:ON
-            log.error("Close transaction engine failed", ex);
-        }
-    }
-}
diff --git 
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java
 
b/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java
index aa37f248cc7..848cc099e50 100644
--- 
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java
+++ 
b/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java
@@ -18,21 +18,28 @@
 package org.apache.shardingsphere.transaction.rule;
 
 import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import org.apache.shardingsphere.infra.rule.scope.GlobalRule;
 import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
+import org.apache.shardingsphere.infra.rule.scope.GlobalRule;
+import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.api.TransactionType;
 import 
org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
 
+import javax.sql.DataSource;
+import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Transaction rule.
  */
 @Getter
-public final class TransactionRule implements GlobalRule {
+@Slf4j
+public final class TransactionRule implements GlobalRule, AutoCloseable {
     
     private final TransactionRuleConfiguration configuration;
     
@@ -42,7 +49,7 @@ public final class TransactionRule implements GlobalRule {
     
     private final Properties props;
     
-    private final Map<String, ShardingSphereDatabase> databases;
+    private final AtomicReference<ShardingSphereTransactionManagerEngine> 
resource;
     
     private final RuleAttributes attributes;
     
@@ -51,7 +58,62 @@ public final class TransactionRule implements GlobalRule {
         defaultType = 
TransactionType.valueOf(ruleConfig.getDefaultType().toUpperCase());
         providerType = ruleConfig.getProviderType();
         props = ruleConfig.getProps();
-        this.databases = new ConcurrentHashMap<>(databases);
-        attributes = new RuleAttributes(new 
TransactionResourceHeldRuleAttribute(defaultType, providerType, 
this.databases));
+        resource = new 
AtomicReference<>(createTransactionManagerEngine(databases));
+        attributes = new RuleAttributes();
+    }
+    
+    private synchronized ShardingSphereTransactionManagerEngine 
createTransactionManagerEngine(final Map<String, ShardingSphereDatabase> 
databases) {
+        if (databases.isEmpty()) {
+            return new ShardingSphereTransactionManagerEngine(defaultType);
+        }
+        Map<String, DatabaseType> databaseTypes = new 
LinkedHashMap<>(databases.size(), 1F);
+        Map<String, DataSource> dataSourceMap = new 
LinkedHashMap<>(databases.size(), 1F);
+        for (Entry<String, ShardingSphereDatabase> entry : 
databases.entrySet()) {
+            ShardingSphereDatabase database = entry.getValue();
+            database.getResourceMetaData().getStorageUnits().forEach((key, 
value) -> {
+                databaseTypes.put(database.getName() + "." + key, 
value.getStorageType());
+                dataSourceMap.put(database.getName() + "." + key, 
value.getDataSource());
+            });
+        }
+        ShardingSphereTransactionManagerEngine result = new 
ShardingSphereTransactionManagerEngine(defaultType);
+        result.init(databaseTypes, dataSourceMap, providerType);
+        return result;
+    }
+    
+    /**
+     * Get resource.
+     * 
+     * @return got resource
+     */
+    public ShardingSphereTransactionManagerEngine getResource() {
+        return resource.get();
+    }
+    
+    @Override
+    public void refresh(final Map<String, ShardingSphereDatabase> databases) {
+        ShardingSphereTransactionManagerEngine previousEngine = resource.get();
+        if (null != previousEngine) {
+            close(previousEngine);
+        }
+        resource.set(createTransactionManagerEngine(databases));
+    }
+    
+    @Override
+    public void close() {
+        ShardingSphereTransactionManagerEngine engine = resource.get();
+        if (null != engine) {
+            close(engine);
+            resource.set(new 
ShardingSphereTransactionManagerEngine(defaultType));
+        }
+    }
+    
+    private void close(final ShardingSphereTransactionManagerEngine engine) {
+        try {
+            engine.close();
+            // CHECKSTYLE:OFF
+        } catch (final RuntimeException ex) {
+            // CHECKSTYLE:ON
+            log.error("Close transaction engine failed.", ex);
+        }
     }
 }
diff --git 
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/TransactionRuleTest.java
 
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/TransactionRuleTest.java
index 2b63897bc69..e9887b42046 100644
--- 
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/TransactionRuleTest.java
+++ 
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/TransactionRuleTest.java
@@ -22,9 +22,7 @@ import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.node.StorageNode;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.api.TransactionType;
 import 
org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
 import 
org.apache.shardingsphere.transaction.core.fixture.ShardingSphereTransactionManagerFixture;
@@ -35,10 +33,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -51,48 +46,24 @@ class TransactionRuleTest {
     
     @Test
     void assertInitTransactionRuleWithMultiDatabaseType() {
-        TransactionRule actual = new 
TransactionRule(createTransactionRuleConfiguration(), 
Collections.singletonMap(SHARDING_DB_1, createDatabase()));
-        
assertNotNull(actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource());
-        assertThat(((ShardingSphereTransactionManagerEngine) 
actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource()).getTransactionManager(TransactionType.XA),
-                instanceOf(ShardingSphereTransactionManagerFixture.class));
+        try (TransactionRule actual = new 
TransactionRule(createTransactionRuleConfiguration(), 
Collections.singletonMap(SHARDING_DB_1, createDatabase()))) {
+            
assertThat(actual.getResource().getTransactionManager(TransactionType.XA), 
instanceOf(ShardingSphereTransactionManagerFixture.class));
+        }
     }
     
     @Test
     void assertAddResource() {
-        TransactionRule actual = new 
TransactionRule(createTransactionRuleConfiguration(), 
Collections.singletonMap(SHARDING_DB_1, createDatabase()));
-        
actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).addResource(createAddDatabase());
-        
assertNotNull(actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource());
-        assertThat(actual.getDatabases().size(), is(2));
-        assertTrue(actual.getDatabases().containsKey(SHARDING_DB_1));
-        ResourceMetaData resourceMetaData1 = 
actual.getDatabases().get(SHARDING_DB_1).getResourceMetaData();
-        assertThat(resourceMetaData1.getStorageUnits().size(), is(2));
-        assertTrue(resourceMetaData1.getStorageUnits().containsKey("ds_0"));
-        assertTrue(resourceMetaData1.getStorageUnits().containsKey("ds_1"));
-        assertTrue(actual.getDatabases().containsKey(SHARDING_DB_2));
-        ResourceMetaData resourceMetaData2 = 
actual.getDatabases().get(SHARDING_DB_2).getResourceMetaData();
-        assertThat(resourceMetaData2.getStorageUnits().size(), is(2));
-        assertTrue(resourceMetaData2.getStorageUnits().containsKey("ds_0"));
-        assertTrue(resourceMetaData2.getStorageUnits().containsKey("ds_1"));
-        assertThat(((ShardingSphereTransactionManagerEngine) 
actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource()).getTransactionManager(TransactionType.XA),
-                instanceOf(ShardingSphereTransactionManagerFixture.class));
-    }
-    
-    @Test
-    void assertCloseStaleResource() {
-        TransactionRule actual = new 
TransactionRule(createTransactionRuleConfiguration(), 
Collections.singletonMap(SHARDING_DB_1, createDatabase()));
-        
actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).dropResource(SHARDING_DB_1);
-        assertTrue(actual.getDatabases().isEmpty());
-        assertThat(((ShardingSphereTransactionManagerEngine) 
actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource()).getTransactionManager(TransactionType.XA),
-                instanceOf(ShardingSphereTransactionManagerFixture.class));
+        try (TransactionRule actual = new 
TransactionRule(createTransactionRuleConfiguration(), 
Collections.singletonMap(SHARDING_DB_1, createDatabase()))) {
+            actual.refresh(Collections.singletonMap(SHARDING_DB_2, 
createAddDatabase()));
+            
assertThat(actual.getResource().getTransactionManager(TransactionType.XA), 
instanceOf(ShardingSphereTransactionManagerFixture.class));
+        }
     }
     
     @Test
-    void assertCloseAllStaleResources() {
+    void assertClose() {
         TransactionRule actual = new 
TransactionRule(createTransactionRuleConfiguration(), 
Collections.singletonMap(SHARDING_DB_1, createDatabase()));
-        
actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).close();
-        assertTrue(actual.getDatabases().isEmpty());
-        assertThat(((ShardingSphereTransactionManagerEngine) 
actual.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource()).getTransactionManager(TransactionType.XA),
-                instanceOf(ShardingSphereTransactionManagerFixture.class));
+        actual.close();
+        
assertThat(actual.getResource().getTransactionManager(TransactionType.XA), 
instanceOf(ShardingSphereTransactionManagerFixture.class));
     }
     
     private ShardingSphereDatabase createDatabase() {
diff --git 
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java
 
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java
index 6c849097247..953c72ad876 100644
--- 
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java
+++ 
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java
@@ -35,8 +35,6 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.mockito.Mockito.mock;
 
@@ -47,9 +45,9 @@ class TransactionRuleBuilderTest {
         TransactionRuleConfiguration ruleConfig = new 
TransactionRuleConfiguration("LOCAL", "provider", new Properties());
         ShardingSphereDatabase database = new 
ShardingSphereDatabase("logic_db", null, new 
ResourceMetaData(createDataSourceMap()),
                 new 
RuleMetaData(Collections.singletonList(mock(ShardingSphereRule.class))), 
Collections.singletonMap("test", mock(ShardingSphereSchema.class)));
-        TransactionRule rule = new TransactionRuleBuilder().build(ruleConfig, 
Collections.singletonMap(DefaultDatabase.LOGIC_NAME, database), 
mock(ConfigurationProperties.class));
-        assertNotNull(rule.getConfiguration());
-        
assertThat(rule.getDatabases().get("logic_db").getResourceMetaData().getStorageUnits().size(),
 is(2));
+        try (TransactionRule rule = new 
TransactionRuleBuilder().build(ruleConfig, 
Collections.singletonMap(DefaultDatabase.LOGIC_NAME, database), 
mock(ConfigurationProperties.class))) {
+            assertNotNull(rule.getConfiguration());
+        }
     }
     
     private Map<String, DataSource> createDataSourceMap() {
diff --git 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
index 93c37664239..acebea5d8f4 100644
--- 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
+++ 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.mode.manager.context;
 
 import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shardingsphere.infra.config.database.DatabaseConfiguration;
 import 
org.apache.shardingsphere.infra.config.database.impl.DataSourceProvidedDatabaseConfiguration;
@@ -37,8 +38,6 @@ import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import 
org.apache.shardingsphere.infra.rule.builder.database.DatabaseRulesBuilder;
 import org.apache.shardingsphere.infra.rule.builder.global.GlobalRulesBuilder;
-import org.apache.shardingsphere.infra.rule.scope.DatabaseRule;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.metadata.factory.ExternalMetaDataFactory;
 import org.apache.shardingsphere.metadata.factory.InternalMetaDataFactory;
 import org.apache.shardingsphere.metadata.persist.MetaDataBasedPersistService;
@@ -79,7 +78,7 @@ public final class ConfigurationContextManager {
      */
     public synchronized void registerStorageUnit(final String databaseName, 
final Map<String, DataSourcePoolProperties> propsMap) {
         try {
-            
getStaleResourceHeldRules(databaseName).forEach(ResourceHeldRuleAttribute::close);
+            closeStaleRules(databaseName);
             SwitchingResource switchingResource =
                     new 
NewResourceSwitchManager().registerStorageUnit(metaDataContexts.get().getMetaData().getDatabase(databaseName).getResourceMetaData(),
 propsMap);
             buildNewMetaDataContext(databaseName, switchingResource);
@@ -96,7 +95,7 @@ public final class ConfigurationContextManager {
      */
     public synchronized void alterStorageUnit(final String databaseName, final 
Map<String, DataSourcePoolProperties> propsMap) {
         try {
-            
getStaleResourceHeldRules(databaseName).forEach(ResourceHeldRuleAttribute::close);
+            closeStaleRules(databaseName);
             SwitchingResource switchingResource =
                     new 
NewResourceSwitchManager().alterStorageUnit(metaDataContexts.get().getMetaData().getDatabase(databaseName).getResourceMetaData(),
 propsMap);
             buildNewMetaDataContext(databaseName, switchingResource);
@@ -113,7 +112,7 @@ public final class ConfigurationContextManager {
      */
     public synchronized void unregisterStorageUnit(final String databaseName, 
final String storageUnitName) {
         try {
-            
getStaleResourceHeldRules(databaseName).forEach(ResourceHeldRuleAttribute::close);
+            closeStaleRules(databaseName);
             SwitchingResource switchingResource = new 
NewResourceSwitchManager().unregisterStorageUnit(metaDataContexts.get().getMetaData().getDatabase(databaseName).getResourceMetaData(),
                     Collections.singletonList(storageUnitName));
             buildNewMetaDataContext(databaseName, switchingResource);
@@ -145,7 +144,7 @@ public final class ConfigurationContextManager {
     public synchronized void alterRuleConfiguration(final String databaseName, 
final Collection<RuleConfiguration> ruleConfigs) {
         try {
             // TODO consider rename this method to 
alterDatabaseRuleConfiguration
-            
getStaleResourceHeldRules(databaseName).stream().filter(DatabaseRule.class::isInstance).forEach(ResourceHeldRuleAttribute::close);
+            closeStaleRules(databaseName);
             MetaDataContexts reloadMetaDataContexts = 
createMetaDataContextsWhenRuleChanged(databaseName, false, null, ruleConfigs);
             alterSchemaMetaData(databaseName, 
reloadMetaDataContexts.getMetaData().getDatabase(databaseName), 
metaDataContexts.get().getMetaData().getDatabase(databaseName));
             metaDataContexts.set(reloadMetaDataContexts);
@@ -226,7 +225,7 @@ public final class ConfigurationContextManager {
      */
     public synchronized void alterDataSourceUnitsConfiguration(final String 
databaseName, final Map<String, DataSourcePoolProperties> propsMap) {
         try {
-            
getStaleResourceHeldRules(databaseName).forEach(ResourceHeldRuleAttribute::close);
+            closeStaleRules(databaseName);
             SwitchingResource switchingResource =
                     new 
ResourceSwitchManager().createByAlterDataSourcePoolProperties(metaDataContexts.get().getMetaData().getDatabase(databaseName).getResourceMetaData(),
 propsMap);
             
metaDataContexts.get().getMetaData().getDatabases().putAll(renewDatabase(metaDataContexts.get().getMetaData().getDatabase(databaseName),
 switchingResource));
@@ -294,11 +293,13 @@ public final class ConfigurationContextManager {
         return result;
     }
     
-    @SuppressWarnings("rawtypes")
-    private Collection<ResourceHeldRuleAttribute> 
getStaleResourceHeldRules(final String databaseName) {
-        Collection<ResourceHeldRuleAttribute> result = 
metaDataContexts.get().getMetaData().getDatabase(databaseName).getRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class);
-        
result.addAll(metaDataContexts.get().getMetaData().getGlobalRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class));
-        return result;
+    @SneakyThrows(Exception.class)
+    private void closeStaleRules(final String databaseName) {
+        for (ShardingSphereRule each : 
metaDataContexts.get().getMetaData().getDatabase(databaseName).getRuleMetaData().getRules())
 {
+            if (each instanceof AutoCloseable) {
+                ((AutoCloseable) each).close();
+            }
+        }
     }
     
     /**
@@ -412,7 +413,7 @@ public final class ConfigurationContextManager {
         if (ruleConfigs.isEmpty()) {
             return;
         }
-        
metaDataContexts.get().getMetaData().getGlobalRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class).forEach(ResourceHeldRuleAttribute::close);
+        closeStaleGlobalRules();
         RuleMetaData toBeChangedGlobalRuleMetaData = new RuleMetaData(
                 GlobalRulesBuilder.buildRules(ruleConfigs, 
metaDataContexts.get().getMetaData().getDatabases(), 
metaDataContexts.get().getMetaData().getProps()));
         ShardingSphereMetaData toBeChangedMetaData = new 
ShardingSphereMetaData(metaDataContexts.get().getMetaData().getDatabases(), 
metaDataContexts.get().getMetaData().getGlobalResourceMetaData(),
@@ -444,6 +445,15 @@ public final class ConfigurationContextManager {
         return result;
     }
     
+    @SneakyThrows(Exception.class)
+    private void closeStaleGlobalRules() {
+        for (ShardingSphereRule each : 
metaDataContexts.get().getMetaData().getGlobalRuleMetaData().getRules()) {
+            if (each instanceof AutoCloseable) {
+                ((AutoCloseable) each).close();
+            }
+        }
+    }
+    
     /**
      * Alter properties.
      *
diff --git 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java
 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java
index 8d71d41533d..dc0e794aa50 100644
--- 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java
+++ 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/MetaDataContexts.java
@@ -18,21 +18,23 @@
 package org.apache.shardingsphere.mode.metadata;
 
 import lombok.Getter;
+import lombok.SneakyThrows;
 import 
org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData;
 import 
org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
-import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereDatabaseData;
 import 
org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereSchemaData;
 import 
org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereStatistics;
 import 
org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereTableData;
 import 
org.apache.shardingsphere.infra.metadata.statistics.builder.ShardingSphereStatisticsBuilder;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.metadata.persist.MetaDataBasedPersistService;
 
+import java.util.Collection;
+import java.util.LinkedList;
 import java.util.Map.Entry;
 import java.util.Optional;
 
@@ -96,12 +98,20 @@ public final class MetaDataContexts implements 
AutoCloseable {
         }
     }
     
+    @SneakyThrows(Exception.class)
     @Override
     public void close() {
         persistService.getRepository().close();
-        
metaData.getGlobalRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class).forEach(ResourceHeldRuleAttribute::close);
-        for (ShardingSphereDatabase each : metaData.getDatabases().values()) {
-            
each.getRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class).forEach(ResourceHeldRuleAttribute::close);
+        for (ShardingSphereRule each : getAllRules()) {
+            if (each instanceof AutoCloseable) {
+                ((AutoCloseable) each).close();
+            }
         }
     }
+    
+    private Collection<ShardingSphereRule> getAllRules() {
+        Collection<ShardingSphereRule> result = new 
LinkedList<>(metaData.getGlobalRuleMetaData().getRules());
+        metaData.getDatabases().values().stream().map(each -> 
each.getRuleMetaData().getRules()).forEach(result::addAll);
+        return result;
+    }
 }
diff --git 
a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/MetaDataContextsFactoryTest.java
 
b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/MetaDataContextsFactoryTest.java
index fd52bc64702..05a40ef3dba 100644
--- 
a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/MetaDataContextsFactoryTest.java
+++ 
b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/MetaDataContextsFactoryTest.java
@@ -86,6 +86,7 @@ class MetaDataContextsFactoryTest {
         
when(metaDataPersistService.getDatabaseMetaDataService()).thenReturn(databaseMetaDataPersistService);
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
         
when(database.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "FIXTURE"));
+        
when(database.getRuleMetaData().getRules()).thenReturn(Collections.emptyList());
         when(ExternalMetaDataFactory.create(anyMap(), any(), 
any())).thenReturn(new HashMap<>(Collections.singletonMap("foo_db", database)));
         when(GlobalRulesBuilder.buildRules(anyCollection(), anyMap(), 
any(ConfigurationProperties.class))).thenReturn(Collections.singleton(new 
MockedRule()));
     }
diff --git 
a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/NewStandaloneModeContextManager.java
 
b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/NewStandaloneModeContextManager.java
index 8cfd7db0fae..e711ad0fc2c 100644
--- 
a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/NewStandaloneModeContextManager.java
+++ 
b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/NewStandaloneModeContextManager.java
@@ -31,7 +31,7 @@ import 
org.apache.shardingsphere.infra.metadata.database.schema.pojo.AlterSchema
 import org.apache.shardingsphere.infra.metadata.version.MetaDataVersion;
 import 
org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute;
 import 
org.apache.shardingsphere.infra.rule.attribute.metadata.MetaDataHeldRuleAttribute;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
+import org.apache.shardingsphere.infra.rule.scope.GlobalRule;
 import 
org.apache.shardingsphere.infra.spi.type.ordered.cache.OrderedServicesCache;
 import 
org.apache.shardingsphere.metadata.persist.service.config.global.GlobalPersistService;
 import 
org.apache.shardingsphere.metadata.persist.service.database.DatabaseMetaDataBasedPersistService;
@@ -212,8 +212,8 @@ public final class NewStandaloneModeContextManager 
implements ModeContextManager
         SwitchingResource switchingResource =
                 new 
NewResourceSwitchManager().registerStorageUnit(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(),
 toBeRegisteredProps);
         
contextManager.getMetaDataContexts().getMetaData().getDatabases().putAll(contextManager.getConfigurationContextManager().createChangedDatabases(databaseName,
 false, switchingResource, null));
-        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class)
-                .forEach(each -> 
each.addResource(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName)));
+        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getRules()
+                .forEach(each -> ((GlobalRule) 
each).refresh(contextManager.getMetaDataContexts().getMetaData().getDatabases()));
         
contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getSchemas()
                 .forEach((schemaName, schema) -> 
contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService()
                         
.persist(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getName(),
 schemaName, schema));
@@ -227,8 +227,8 @@ public final class NewStandaloneModeContextManager 
implements ModeContextManager
         SwitchingResource switchingResource =
                 new 
NewResourceSwitchManager().alterStorageUnit(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(),
 toBeUpdatedProps);
         
contextManager.getMetaDataContexts().getMetaData().getDatabases().putAll(contextManager.getConfigurationContextManager().createChangedDatabases(databaseName,
 true, switchingResource, null));
-        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class)
-                .forEach(each -> 
each.addResource(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName)));
+        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getRules()
+                .forEach(each -> ((GlobalRule) 
each).refresh(contextManager.getMetaDataContexts().getMetaData().getDatabases()));
         
contextManager.getMetaDataContexts().getPersistService().getDataSourceUnitService().append(
                 
contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getName(),
 toBeUpdatedProps);
         switchingResource.closeStaleDataSources();
diff --git 
a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
 
b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
index 95a84b9aa26..646d770fed7 100644
--- 
a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
+++ 
b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
@@ -30,7 +30,7 @@ import 
org.apache.shardingsphere.infra.metadata.database.schema.pojo.AlterSchema
 import 
org.apache.shardingsphere.infra.metadata.database.schema.pojo.AlterSchemaPOJO;
 import 
org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute;
 import 
org.apache.shardingsphere.infra.rule.attribute.metadata.MetaDataHeldRuleAttribute;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
+import org.apache.shardingsphere.infra.rule.scope.GlobalRule;
 import 
org.apache.shardingsphere.infra.spi.type.ordered.cache.OrderedServicesCache;
 import 
org.apache.shardingsphere.metadata.persist.service.database.DatabaseMetaDataBasedPersistService;
 import org.apache.shardingsphere.mode.manager.ContextManager;
@@ -204,8 +204,8 @@ public final class StandaloneModeContextManager implements 
ModeContextManager, C
         SwitchingResource switchingResource =
                 new 
ResourceSwitchManager().create(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(),
 toBeRegisteredProps);
         
contextManager.getMetaDataContexts().getMetaData().getDatabases().putAll(contextManager.getConfigurationContextManager().createChangedDatabases(databaseName,
 false, switchingResource, null));
-        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class)
-                .forEach(each -> 
each.addResource(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName)));
+        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getRules()
+                .forEach(each -> ((GlobalRule) 
each).refresh(contextManager.getMetaDataContexts().getMetaData().getDatabases()));
         
contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getSchemas()
                 .forEach((schemaName, schema) -> 
contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService()
                         
.persist(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getName(),
 schemaName, schema));
@@ -219,8 +219,8 @@ public final class StandaloneModeContextManager implements 
ModeContextManager, C
         SwitchingResource switchingResource =
                 new 
ResourceSwitchManager().create(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(),
 toBeUpdatedProps);
         
contextManager.getMetaDataContexts().getMetaData().getDatabases().putAll(contextManager.getConfigurationContextManager().createChangedDatabases(databaseName,
 true, switchingResource, null));
-        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getAttributes(ResourceHeldRuleAttribute.class)
-                .forEach(each -> 
each.addResource(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName)));
+        
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getRules()
+                .forEach(each -> ((GlobalRule) 
each).refresh(contextManager.getMetaDataContexts().getMetaData().getDatabases()));
         
contextManager.getMetaDataContexts().getPersistService().getDataSourceUnitService().append(
                 
contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getName(),
 toBeUpdatedProps);
         switchingResource.closeStaleDataSources();
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSource.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSource.java
index 0028e662a6e..76f0cc66b86 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSource.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSource.java
@@ -21,10 +21,8 @@ import com.google.common.base.Preconditions;
 import org.apache.shardingsphere.infra.database.core.GlobalDataSourceRegistry;
 import 
org.apache.shardingsphere.infra.exception.OverallConnectionNotEnoughException;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.ConnectionMode;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.proxy.backend.connector.BackendDataSource;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.api.TransactionType;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import 
org.apache.shardingsphere.transaction.spi.ShardingSphereTransactionManager;
@@ -108,8 +106,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 = 
((ShardingSphereTransactionManagerEngine) 
transactionRule.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource())
-                .getTransactionManager(transactionType);
+        ShardingSphereTransactionManager transactionManager = 
transactionRule.getResource().getTransactionManager(transactionType);
         Connection result = isInTransaction(transactionManager) ? 
transactionManager.getConnection(databaseName, dataSourceName) : 
dataSource.getConnection();
         if (dataSourceName.contains(".")) {
             String catalog = dataSourceName.split("\\.")[1];
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManager.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManager.java
index 86238dd4ce4..0fdbf1bc674 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManager.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManager.java
@@ -17,7 +17,6 @@
 
 package org.apache.shardingsphere.proxy.backend.connector.jdbc.transaction;
 
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import 
org.apache.shardingsphere.infra.session.connection.transaction.TransactionConnectionContext;
 import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
 import 
org.apache.shardingsphere.proxy.backend.connector.ProxyDatabaseConnectionManager;
@@ -56,7 +55,7 @@ public final class BackendTransactionManager implements 
TransactionManager {
         transactionType = 
connection.getConnectionSession().getTransactionStatus().getTransactionType();
         localTransactionManager = new 
LocalTransactionManager(databaseConnectionManager);
         TransactionRule transactionRule = 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(TransactionRule.class);
-        ShardingSphereTransactionManagerEngine engine = 
(ShardingSphereTransactionManagerEngine) 
transactionRule.getAttributes().getAttribute(ResourceHeldRuleAttribute.class).getResource();
+        ShardingSphereTransactionManagerEngine engine = 
transactionRule.getResource();
         shardingSphereTransactionManager = null == engine ? null : 
engine.getTransactionManager(transactionType);
         transactionHooks = 
ShardingSphereServiceLoader.getServiceInstances(TransactionHook.class);
     }
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSourceTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSourceTest.java
index 19e6bfafbd1..2befa7cc819 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSourceTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/datasource/JDBCBackendDataSourceTest.java
@@ -26,8 +26,6 @@ import 
org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.metadata.persist.MetaDataPersistService;
 import org.apache.shardingsphere.mode.manager.ContextManager;
@@ -36,7 +34,6 @@ import 
org.apache.shardingsphere.proxy.backend.connector.jdbc.datasource.fixture
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.test.mock.AutoMockExtension;
 import org.apache.shardingsphere.test.mock.StaticMockSettings;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -87,31 +84,22 @@ class JDBCBackendDataSourceTest {
     
     private ContextManager mockContextManager() {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
-        MetaDataContexts metaDataContexts = new 
MetaDataContexts(mock(MetaDataPersistService.class),
-                new ShardingSphereMetaData(createDatabases(), 
mock(ResourceMetaData.class), mockGlobalRuleMetaData(), new 
ConfigurationProperties(new Properties())));
+        MetaDataContexts metaDataContexts = new 
MetaDataContexts(mock(MetaDataPersistService.class), new ShardingSphereMetaData(
+                createDatabases(), mock(ResourceMetaData.class),
+                new 
RuleMetaData(Collections.singleton(mock(TransactionRule.class, 
RETURNS_DEEP_STUBS))), new ConfigurationProperties(new Properties())));
         when(result.getMetaDataContexts()).thenReturn(metaDataContexts);
         return result;
     }
     
     private Map<String, ShardingSphereDatabase> createDatabases() {
-        DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getProtocolType()).thenReturn(databaseType);
+        
when(database.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "FIXTURE"));
         for (Entry<String, DataSource> entry : mockDataSources(2).entrySet()) {
             
when(database.getResourceMetaData().getStorageUnits().get(entry.getKey()).getDataSource()).thenReturn(entry.getValue());
         }
         return Collections.singletonMap("schema", database);
     }
     
-    @SuppressWarnings("unchecked")
-    private RuleMetaData mockGlobalRuleMetaData() {
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
-        return new RuleMetaData(Collections.singleton(transactionRule));
-    }
-    
     private Map<String, DataSource> mockDataSources(final int size) {
         Map<String, DataSource> result = new HashMap<>(size, 1F);
         for (int i = 0; i < size; i++) {
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManagerTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManagerTest.java
index 73da06c9c80..9f3e235f574 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManagerTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/transaction/BackendTransactionManagerTest.java
@@ -18,11 +18,9 @@
 package org.apache.shardingsphere.proxy.backend.connector.jdbc.transaction;
 
 import lombok.SneakyThrows;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
 import 
org.apache.shardingsphere.infra.session.connection.transaction.TransactionConnectionContext;
-import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import 
org.apache.shardingsphere.proxy.backend.connector.ProxyDatabaseConnectionManager;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
@@ -193,14 +191,11 @@ class BackendTransactionManagerTest {
         return result;
     }
     
-    @SuppressWarnings("unchecked")
     private RuleMetaData mockGlobalRuleMetaData() {
         ShardingSphereTransactionManagerEngine transactionManagerEngine = 
mock(ShardingSphereTransactionManagerEngine.class);
         
when(transactionManagerEngine.getTransactionManager(TransactionType.XA)).thenReturn(shardingSphereTransactionManager);
         TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(transactionManagerEngine);
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
+        
when(transactionRule.getResource()).thenReturn(transactionManagerEngine);
         return new RuleMetaData(Collections.singleton(transactionRule));
     }
 }
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactoryTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactoryTest.java
index 8edf97ec0a0..27ffa5bdfd7 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactoryTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactoryTest.java
@@ -18,15 +18,13 @@
 package org.apache.shardingsphere.proxy.backend.handler.transaction;
 
 import lombok.SneakyThrows;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
-import org.apache.shardingsphere.infra.session.query.QueryContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
 import org.apache.shardingsphere.mode.manager.ContextManager;
-import 
org.apache.shardingsphere.proxy.backend.connector.ProxyDatabaseConnectionManager;
 import org.apache.shardingsphere.proxy.backend.connector.DatabaseConnector;
 import 
org.apache.shardingsphere.proxy.backend.connector.DatabaseConnectorFactory;
+import 
org.apache.shardingsphere.proxy.backend.connector.ProxyDatabaseConnectionManager;
 import 
org.apache.shardingsphere.proxy.backend.connector.jdbc.transaction.BackendTransactionManager;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
@@ -36,7 +34,6 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.RollbackSta
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.TCLStatement;
 import org.apache.shardingsphere.test.mock.AutoMockExtension;
 import org.apache.shardingsphere.test.mock.StaticMockSettings;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.core.TransactionOperationType;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.hamcrest.Matcher;
@@ -95,14 +92,9 @@ class TransactionBackendHandlerFactoryTest {
         
assertFieldOfInstance(getBackendTransactionManager(transactionBackendHandler), 
"connection", is(databaseConnectionManager));
     }
     
-    @SuppressWarnings("unchecked")
     private ContextManager mockContextManager() {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
-        
when(result.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Collections.singleton(transactionRule)));
+        
when(result.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Collections.singleton(mock(TransactionRule.class))));
         return result;
     }
     
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerTest.java
index 51928977dfe..9b80a1d0aa8 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerTest.java
@@ -18,8 +18,6 @@
 package org.apache.shardingsphere.proxy.backend.handler.transaction;
 
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import 
org.apache.shardingsphere.proxy.backend.connector.ProxyDatabaseConnectionManager;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
@@ -28,7 +26,6 @@ import 
org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.TCLStatement;
 import org.apache.shardingsphere.test.mock.AutoMockExtension;
 import org.apache.shardingsphere.test.mock.StaticMockSettings;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.core.TransactionOperationType;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.jupiter.api.Test;
@@ -59,14 +56,9 @@ class TransactionBackendHandlerTest {
         assertThat(new TransactionBackendHandler(mock(TCLStatement.class), 
TransactionOperationType.BEGIN, connectionSession).execute(), 
instanceOf(UpdateResponseHeader.class));
     }
     
-    @SuppressWarnings("unchecked")
     private ContextManager mockContextManager() {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
-        
when(result.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Collections.singleton(transactionRule)));
+        
when(result.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Collections.singleton(mock(TransactionRule.class))));
         return result;
     }
 }
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/session/ConnectionSessionTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/session/ConnectionSessionTest.java
index 9919f43b55f..845ae3c9ad8 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/session/ConnectionSessionTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/session/ConnectionSessionTest.java
@@ -17,18 +17,15 @@
 
 package org.apache.shardingsphere.proxy.backend.session;
 
-import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
-import 
org.apache.shardingsphere.infra.rule.attribute.resoure.ResourceHeldRuleAttribute;
-import org.apache.shardingsphere.infra.session.query.QueryContext;
 import org.apache.shardingsphere.infra.database.mysql.type.MySQLDatabaseType;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import 
org.apache.shardingsphere.proxy.backend.connector.ProxyDatabaseConnectionManager;
 import 
org.apache.shardingsphere.proxy.backend.connector.jdbc.transaction.BackendTransactionManager;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.test.mock.AutoMockExtension;
 import org.apache.shardingsphere.test.mock.StaticMockSettings;
-import 
org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.api.TransactionType;
 import 
org.apache.shardingsphere.transaction.exception.SwitchTypeInTransactionException;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
@@ -93,14 +90,9 @@ class ConnectionSessionTest {
         assertThat(connectionSession.getDefaultDatabaseName(), is("newDB"));
     }
     
-    @SuppressWarnings("unchecked")
     private ContextManager mockContextManager() {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
-        TransactionRule transactionRule = mock(TransactionRule.class);
-        ResourceHeldRuleAttribute<ShardingSphereTransactionManagerEngine> 
resourceHeldRuleAttribute = mock(ResourceHeldRuleAttribute.class);
-        
when(resourceHeldRuleAttribute.getResource()).thenReturn(mock(ShardingSphereTransactionManagerEngine.class));
-        when(transactionRule.getAttributes()).thenReturn(new 
RuleAttributes(resourceHeldRuleAttribute));
-        
when(result.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Collections.singleton(transactionRule)));
+        
when(result.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Collections.singleton(mock(TransactionRule.class))));
         return result;
     }
     


Reply via email to