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

jianbin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new 1076e2b3c0 optimize: Prohibit registration of TCC resources with the 
same name (#6391)
1076e2b3c0 is described below

commit 1076e2b3c07e01b88cc5b99dc45f68e168356587
Author: yiqi <77573225+pleasegivemethec...@users.noreply.github.com>
AuthorDate: Tue Mar 5 21:33:30 2024 +0800

    optimize: Prohibit registration of TCC resources with the same name (#6391)
---
 changes/en-us/2.x.md                               |  1 +
 changes/zh-cn/2.x.md                               |  2 +-
 .../exception/RepeatRegistrationException.java     | 51 ++++++++++++++++++++++
 .../AdapterSpringSeataInterceptorTest.java         | 23 ++++++----
 .../apache/seata/rm/tcc/TCCResourceManager.java    | 32 +++++++++++---
 .../org/apache/seata/rm/tcc/NestTccAction.java     |  2 +-
 .../org/apache/seata/rm/tcc/NormalTccAction.java   |  2 +-
 .../rm/tcc/interceptor/ProxyUtilsTccTest.java      | 23 +++++-----
 .../parser/TccActionInterceptorParserTest.java     |  6 +++
 .../core/rpc/netty/mockserver/RmClientTest.java    |  1 +
 10 files changed, 115 insertions(+), 28 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index fa5ebb56ef..ba6d1b1d3d 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -104,6 +104,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#6366](https://github.com/apache/incubator-seata/pull/6366)] optimized 
globaltransaction compatibility issues
 - [[#6369](https://github.com/apache/incubator-seata/pull/6369)] optimize 
arm64 ci
 - [[#6386](https://github.com/apache/incubator-seata/pull/6386)] replace 
`byte-buddy` to JDK proxy in `ConfigurationCache`
+- [[#6391](https://github.com/apache/incubator-seata/pull/6091)] forbid 
duplicate registration of TCC resources
 
 ### refactor:
 - [[#6269](https://github.com/apache/incubator-seata/pull/6269)] standardize 
Seata Exception
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 5c7ff19985..446dd5558e 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -108,7 +108,7 @@
 - [[#6366](https://github.com/apache/incubator-seata/pull/6366)] 
优化globaltransaction向下兼容性
 - [[#6369](https://github.com/apache/incubator-seata/pull/6369)] 优化 arm64 ci
 - [[#6386](https://github.com/apache/incubator-seata/pull/6386)] 在 
`ConfigurationCache` 类中,将 `byte-buddy` 替换为JDK代理
-
+- [[#6391](https://github.com/apache/incubator-seata/pull/6091)] 禁止重复注册TCC资源
 
 
 ### refactor:
diff --git 
a/common/src/main/java/org/apache/seata/common/exception/RepeatRegistrationException.java
 
b/common/src/main/java/org/apache/seata/common/exception/RepeatRegistrationException.java
new file mode 100644
index 0000000000..127d544c9c
--- /dev/null
+++ 
b/common/src/main/java/org/apache/seata/common/exception/RepeatRegistrationException.java
@@ -0,0 +1,51 @@
+/*
+ * 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.seata.common.exception;
+
+/**
+ * The repeat registration exception.
+ */
+public class RepeatRegistrationException extends RuntimeException {
+
+    /**
+     * Instantiates a new RepeatRegistrationException.
+     *
+     * @param message the message
+     */
+    public RepeatRegistrationException(String message) {
+        super(message);
+    }
+
+    /**
+     * Instantiates a new RepeatRegistrationException.
+     *
+     * @param message the message
+     * @param cause   the cause
+     */
+    public RepeatRegistrationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Instantiates a new RepeatRegistrationException.
+     *
+     * @param cause the cause
+     */
+    public RepeatRegistrationException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file
diff --git 
a/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java
 
b/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java
index da8fc35961..e1d0e19e48 100644
--- 
a/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java
+++ 
b/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java
@@ -29,6 +29,7 @@ import org.apache.seata.spring.tcc.NormalTccAction;
 import org.apache.seata.spring.tcc.NormalTccActionImpl;
 import org.aopalliance.intercept.MethodInvocation;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -36,12 +37,20 @@ import org.junit.jupiter.api.Test;
  */
 class AdapterSpringSeataInterceptorTest {
 
-    @Test
-    void should_throw_raw_exception_when_call_prepareWithException() throws 
Throwable {
+    private static NormalTccAction normalTccAction;
+
+    private static AdapterSpringSeataInterceptor adapterSpringSeataInterceptor;
+
+    @BeforeAll
+    static void init() throws Throwable {
         //given
-        NormalTccActionImpl normalTccAction = new NormalTccActionImpl();
+        normalTccAction = new NormalTccActionImpl();
         ProxyInvocationHandler proxyInvocationHandler = 
DefaultInterfaceParser.get().parserInterfaceToProxy(normalTccAction, 
"proxyTccAction");
-        AdapterSpringSeataInterceptor adapterSpringSeataInterceptor = new 
AdapterSpringSeataInterceptor(proxyInvocationHandler);
+        adapterSpringSeataInterceptor = new 
AdapterSpringSeataInterceptor(proxyInvocationHandler);
+    }
+
+    @Test
+    void should_throw_raw_exception_when_call_prepareWithException() throws 
Throwable {
         MyMockMethodInvocation myMockMethodInvocation = new 
MyMockMethodInvocation(NormalTccAction.class.getMethod("prepareWithException", 
BusinessActionContext.class), () -> normalTccAction.prepareWithException(null));
 
         //when then
@@ -50,10 +59,6 @@ class AdapterSpringSeataInterceptorTest {
 
     @Test
     void should_success_when_call_prepare_with_ProxyInvocationHandler() throws 
Throwable {
-        //given
-        NormalTccActionImpl normalTccAction = new NormalTccActionImpl();
-        ProxyInvocationHandler proxyInvocationHandler = 
DefaultInterfaceParser.get().parserInterfaceToProxy(normalTccAction, 
"proxyTccAction");
-        AdapterSpringSeataInterceptor adapterSpringSeataInterceptor = new 
AdapterSpringSeataInterceptor(proxyInvocationHandler);
         MyMockMethodInvocation myMockMethodInvocation = new 
MyMockMethodInvocation(NormalTccAction.class.getMethod("prepare", 
BusinessActionContext.class), () -> normalTccAction.prepare(null));
 
         //when then
@@ -100,4 +105,4 @@ class AdapterSpringSeataInterceptorTest {
             return null;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java 
b/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java
index 83c1d70e5c..c19f08604c 100644
--- a/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java
+++ b/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.seata.common.Constants;
+import org.apache.seata.common.exception.RepeatRegistrationException;
 import org.apache.seata.common.exception.ShouldNeverHappenException;
 import org.apache.seata.common.exception.SkipCallbackWrapperException;
 import org.apache.seata.core.exception.TransactionException;
@@ -59,16 +60,35 @@ public class TCCResourceManager extends 
AbstractResourceManager {
      */
     @Override
     public void registerResource(Resource resource) {
-        TCCResource tccResource = (TCCResource)resource;
-        tccResourceCache.put(tccResource.getResourceId(), tccResource);
-        super.registerResource(tccResource);
+        String resourceId = resource.getResourceId();
+        TCCResource newResource = (TCCResource) resource;
+        TCCResource oldResource = getTCCResource(resourceId);
+
+        if (oldResource != null) {
+            Object newResourceBean = newResource.getTargetBean();
+            Object oldResourceBean = oldResource.getTargetBean();
+            if (newResourceBean != oldResourceBean) {
+                throw new RepeatRegistrationException(String.format("Same TCC 
resource name <%s> between method1 <%s> of class1 <%s> and method2 <%s> of 
class2 <%s>, should be unique",
+                        resourceId,
+                        newResource.getPrepareMethod().getName(),
+                        newResourceBean.getClass().getName(),
+                        oldResource.getPrepareMethod().getName(),
+                        oldResourceBean.getClass().getName()));
+            }
+        }
+
+        tccResourceCache.put(resourceId, newResource);
+        super.registerResource(newResource);
+    }
+
+    public TCCResource getTCCResource(String resourceId) {
+        return (TCCResource) tccResourceCache.get(resourceId);
     }
 
     @Override
     public Map<String, Resource> getManagedResources() {
         return tccResourceCache;
     }
-
     /**
      * TCC branch commit
      *
@@ -83,7 +103,7 @@ public class TCCResourceManager extends 
AbstractResourceManager {
     @Override
     public BranchStatus branchCommit(BranchType branchType, String xid, long 
branchId, String resourceId,
                                      String applicationData) throws 
TransactionException {
-        TCCResource tccResource = 
(TCCResource)tccResourceCache.get(resourceId);
+        TCCResource tccResource = getTCCResource(resourceId);
         if (tccResource == null) {
             throw new ShouldNeverHappenException(String.format("TCC resource 
is not exist, resourceId: %s", resourceId));
         }
@@ -142,7 +162,7 @@ public class TCCResourceManager extends 
AbstractResourceManager {
     @Override
     public BranchStatus branchRollback(BranchType branchType, String xid, long 
branchId, String resourceId,
                                        String applicationData) throws 
TransactionException {
-        TCCResource tccResource = 
(TCCResource)tccResourceCache.get(resourceId);
+        TCCResource tccResource = getTCCResource(resourceId);
         if (tccResource == null) {
             throw new ShouldNeverHappenException(String.format("TCC resource 
is not exist, resourceId: %s", resourceId));
         }
diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java 
b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java
index 19fe35a8f8..3cd40fc85a 100644
--- a/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java
+++ b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java
@@ -35,7 +35,7 @@ public interface NestTccAction {
     @TwoPhaseBusinessAction(name = "tccNestActionForTest")
     boolean prepare(BusinessActionContext actionContext, int count);
 
-    @TwoPhaseBusinessAction(name = "tccNestActionForTest")
+    @TwoPhaseBusinessAction(name = "tccNestActionRequiredNewForTest")
     boolean prepareNestRequiredNew(BusinessActionContext actionContext, int 
count);
 
     /**
diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java 
b/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java
index 8fccb820be..a2c44f7816 100644
--- a/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java
+++ b/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java
@@ -39,7 +39,7 @@ public interface NormalTccAction {
      * @param tccParam      the tcc param
      * @return the boolean
      */
-    @TwoPhaseBusinessAction(name = "tccActionForTest", commitMethod = 
"commit", rollbackMethod = "rollback", commitArgsClasses = 
{BusinessActionContext.class, TccParam.class}, rollbackArgsClasses = 
{BusinessActionContext.class, TccParam.class})
+    @TwoPhaseBusinessAction(name = "normalTccActionForTest", commitMethod = 
"commit", rollbackMethod = "rollback", commitArgsClasses = 
{BusinessActionContext.class, TccParam.class}, rollbackArgsClasses = 
{BusinessActionContext.class, TccParam.class})
     String prepare(BusinessActionContext actionContext,
                     @BusinessActionContextParameter("a") int a,
                     @BusinessActionContextParameter(paramName = "b", index = 
0) List b,
diff --git 
a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java 
b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java
index 9a243733e9..87fb8083b1 100644
--- 
a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java
+++ 
b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.seata.rm.tcc.interceptor;
 
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -30,10 +31,10 @@ import org.apache.seata.core.model.Resource;
 import org.apache.seata.core.model.ResourceManager;
 import org.apache.seata.integration.tx.api.util.ProxyUtil;
 import org.apache.seata.rm.DefaultResourceManager;
-import org.apache.seata.rm.tcc.NormalTccAction;
 import org.apache.seata.rm.tcc.NormalTccActionImpl;
 import org.apache.seata.rm.tcc.TccParam;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 
@@ -41,6 +42,10 @@ public class ProxyUtilsTccTest {
 
     private final String DEFAULT_XID = "default_xid";
 
+    private static NormalTccActionImpl tccAction;
+
+    private static NormalTccActionImpl tccActionProxy;
+
     AtomicReference<String> branchReference = new AtomicReference<String>();
 
 
@@ -100,12 +105,16 @@ public class ProxyUtilsTccTest {
 
     };
 
+    @BeforeAll
+    public static void init() throws IOException {
+        tccAction = new NormalTccActionImpl();
+        tccActionProxy = ProxyUtil.createProxy(tccAction);
+    }
+
 
     @Test
     public void testTcc() {
         //given
-        NormalTccActionImpl tccAction = new NormalTccActionImpl();
-        NormalTccAction tccActionProxy = ProxyUtil.createProxy(tccAction);
         RootContext.bind(DEFAULT_XID);
 
         TccParam tccParam = new TccParam(1, "a...@163.com");
@@ -119,14 +128,12 @@ public class ProxyUtilsTccTest {
         //then
         Assertions.assertEquals("a", result);
         Assertions.assertNotNull(result);
-        Assertions.assertEquals("tccActionForTest", branchReference.get());
+        Assertions.assertEquals("normalTccActionForTest", 
branchReference.get());
     }
 
     @Test
     public void testTccThrowRawException() {
         //given
-        NormalTccActionImpl tccAction = new NormalTccActionImpl();
-        NormalTccAction tccActionProxy = ProxyUtil.createProxy(tccAction);
         RootContext.bind(DEFAULT_XID);
 
         TccParam tccParam = new TccParam(1, "a...@163.com");
@@ -141,11 +148,7 @@ public class ProxyUtilsTccTest {
 
     @Test
     public void testTccImplementOtherMethod(){
-        NormalTccActionImpl tccAction = new NormalTccActionImpl();
-        NormalTccActionImpl tccActionProxy = ProxyUtil.createProxy(tccAction);
-
         Assertions.assertTrue(tccActionProxy.otherMethod());
-
     }
 
 
diff --git 
a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java
 
b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java
index 0f19353553..867b9c2de9 100644
--- 
a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java
+++ 
b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java
@@ -43,6 +43,7 @@ import org.apache.seata.rm.tcc.TccActionImpl;
 import org.apache.seata.tm.TransactionManagerHolder;
 import org.apache.seata.tm.api.GlobalTransaction;
 import org.apache.seata.tm.api.GlobalTransactionContext;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -58,6 +59,11 @@ class TccActionInterceptorParserTest {
         System.setProperty("service.vgroupMapping.default_tx_group", 
"default");
     }
 
+    @AfterEach
+    public void clearTccResource(){
+        resourceManager.getManagedResources().clear();
+    }
+
     @Test
     void parserInterfaceToProxy() {
 
diff --git 
a/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java
 
b/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java
index fcfb0a9052..671f1d4431 100644
--- 
a/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java
+++ 
b/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java
@@ -78,6 +78,7 @@ public class RmClientTest {
     public static DefaultResourceManager getRm(String resourceId) {
         RMClient.init(ProtocolTestConstants.APPLICATION_ID, 
ProtocolTestConstants.SERVICE_GROUP);
         DefaultResourceManager rm = DefaultResourceManager.get();
+        rm.getResourceManager(BranchType.TCC).getManagedResources().clear();
 
         //register:TYPE_REG_RM = 103 , TYPE_REG_RM_RESULT = 104
         Action1 target = new Action1Impl();


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org
For additional commands, e-mail: notifications-h...@seata.apache.org

Reply via email to