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 1939a9f717 bugfix: TwoPhaseBusinessAction coexist with
GlobalTransactional (#6331)
1939a9f717 is described below
commit 1939a9f7177074b97fbd8a3821f139baf33061f3
Author: leezongjie <[email protected]>
AuthorDate: Wed Feb 28 16:28:34 2024 +0800
bugfix: TwoPhaseBusinessAction coexist with GlobalTransactional (#6331)
---
changes/en-us/2.x.md | 1 +
changes/zh-cn/2.x.md | 1 +
...tionHandler.java => InvocationHandlerType.java} | 20 +-
.../interceptor/NestInterceptorHandlerWrapper.java | 58 ++++
.../handler/AbstractProxyInvocationHandler.java | 10 +
.../GlobalTransactionalInterceptorHandler.java | 24 +-
.../handler/ProxyInvocationHandler.java | 7 +
.../interceptor/parser/DefaultInterfaceParser.java | 45 ++-
.../GlobalTransactionalInterceptorParser.java | 2 -
.../interceptor/TccActionInterceptorHandler.java | 13 +-
.../parser/TccActionInterceptorParser.java | 2 -
.../org/apache/seata/rm/tcc/BranchSessionMock.java | 85 ++++++
.../rm/tcc/{TccAction.java => NestTccAction.java} | 24 +-
.../{TccActionImpl.java => NestTccActionImpl.java} | 45 ++-
.../java/org/apache/seata/rm/tcc/TccAction.java | 29 +-
.../org/apache/seata/rm/tcc/TccActionImpl.java | 34 ++-
.../parser/TccActionInterceptorParserTest.java | 328 +++++++++++++++++++++
.../parser/TccRegisterResourceParserTest.java | 10 +-
18 files changed, 641 insertions(+), 97 deletions(-)
diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 327e258809..4d291c9a98 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -24,6 +24,7 @@ Add changes here for all PR submitted to the 2.x branch.
- [[#6232](https://github.com/apache/incubator-seata/pull/6232)] convert to
utf8mb4 if mysql column is json type
- [[#6278](https://github.com/apache/incubator-seata/pull/6278)] fix
ProtocolV1SerializerTest failed
- [[#6324](https://github.com/apache/incubator-seata/pull/6324)] fix Parse
protocol file failed
+- [[#6331](https://github.com/apache/incubator-seata/pull/6331)] fixed the
problem that TCC nested transactions cannot add TwoPhaseBusinessAction and
GlobalTransactional annotations at the same time
- [[#6354](https://github.com/apache/incubator-seata/pull/6354)] fix dynamic
degradation does not work properly
- [[#6363](https://github.com/apache/incubator-seata/pull/6363)] fix known
problems of docker image
- [[#6372](https://github.com/apache/incubator-seata/pull/6372)] fix
initializing the sql file postgresql.sql index name conflict
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 5c60b573d6..afa94b86b4 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -24,6 +24,7 @@
- [[#6232](https://github.com/apache/incubator-seata/pull/6232)]
修复在mysql的json类型下出现Cannot create a JSON value from a string with CHARACTER SET
'binary'问题
- [[#6278](https://github.com/apache/incubator-seata/pull/6278)] 修复
ProtocolV1SerializerTest 失败问题
- [[#6324](https://github.com/apache/incubator-seata/pull/6324)] 修复 Parse
protocol file failed
+- [[#6331](https://github.com/apache/incubator-seata/pull/6331)]
修复TCC嵌套事务不能同时添加TwoPhaseBusinessAction和GlobalTransactional两个注解的问题
- [[#6354](https://github.com/apache/incubator-seata/pull/6354)]
修复动态升降级不能正常工作问题
- [[#6363](https://github.com/apache/incubator-seata/pull/6363)]
修复docker镜像中的已知问题
- [[#6372](https://github.com/apache/incubator-seata/pull/6372)]
修复初始化sql文件postgresql.sql 索引名称冲突问题
diff --git
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/ProxyInvocationHandler.java
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/InvocationHandlerType.java
similarity index 60%
copy from
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/ProxyInvocationHandler.java
copy to
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/InvocationHandlerType.java
index 8238d8526b..7d909105a0 100644
---
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/ProxyInvocationHandler.java
+++
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/InvocationHandlerType.java
@@ -14,21 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.seata.integration.tx.api.interceptor.handler;
+package org.apache.seata.integration.tx.api.interceptor;
-import java.util.Set;
-
-import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
-import org.apache.seata.integration.tx.api.interceptor.SeataInterceptor;
-import
org.apache.seata.integration.tx.api.interceptor.SeataInterceptorPosition;
-
-
-public interface ProxyInvocationHandler extends SeataInterceptor {
-
- Set<String> getMethodsToProxy();
-
- Object invoke(InvocationWrapper invocation) throws Throwable;
+/**
+ * The InvocationHandlerType enum
+ */
+public enum InvocationHandlerType {
- SeataInterceptorPosition getPosition();
+ GlobalTransactional, TwoPhaseAnnotation
}
diff --git
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/NestInterceptorHandlerWrapper.java
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/NestInterceptorHandlerWrapper.java
new file mode 100644
index 0000000000..0abb2fc4bd
--- /dev/null
+++
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/NestInterceptorHandlerWrapper.java
@@ -0,0 +1,58 @@
+/*
+ * 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.integration.tx.api.interceptor;
+
+import java.lang.reflect.Method;
+import
org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
+
+
+public class NestInterceptorHandlerWrapper implements InvocationWrapper {
+
+ private ProxyInvocationHandler proxyInvocationHandler;
+
+ private InvocationWrapper invocation;
+
+ public NestInterceptorHandlerWrapper(ProxyInvocationHandler
proxyInvocationHandler, InvocationWrapper invocation) {
+ this.proxyInvocationHandler = proxyInvocationHandler;
+ this.invocation = invocation;
+ }
+
+ @Override
+ public Method getMethod() {
+ return invocation.getMethod();
+ }
+
+ @Override
+ public Object getProxy() {
+ return invocation.getProxy();
+ }
+
+ @Override
+ public Object getTarget() {
+ return invocation.getTarget();
+ }
+
+ @Override
+ public Object[] getArguments() {
+ return invocation.getArguments();
+ }
+
+ @Override
+ public Object proceed() throws Throwable {
+ return proxyInvocationHandler.invoke(invocation);
+ }
+}
diff --git
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/AbstractProxyInvocationHandler.java
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/AbstractProxyInvocationHandler.java
index f6c3a53385..76429b7a50 100644
---
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/AbstractProxyInvocationHandler.java
+++
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/AbstractProxyInvocationHandler.java
@@ -18,6 +18,7 @@ package
org.apache.seata.integration.tx.api.interceptor.handler;
import org.apache.seata.common.util.CollectionUtils;
import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
+import
org.apache.seata.integration.tx.api.interceptor.NestInterceptorHandlerWrapper;
public abstract class AbstractProxyInvocationHandler implements
ProxyInvocationHandler {
@@ -26,11 +27,16 @@ public abstract class AbstractProxyInvocationHandler
implements ProxyInvocationH
protected int order = Integer.MAX_VALUE;
+ protected ProxyInvocationHandler nextInvocationHandlerChain;
+
@Override
public Object invoke(InvocationWrapper invocation) throws Throwable {
if (CollectionUtils.isNotEmpty(getMethodsToProxy()) &&
!getMethodsToProxy().contains(invocation.getMethod().getName())) {
return invocation.proceed();
}
+ if (nextInvocationHandlerChain != null) {
+ invocation = new
NestInterceptorHandlerWrapper(nextInvocationHandlerChain, invocation);
+ }
return doInvoke(invocation);
}
@@ -44,4 +50,8 @@ public abstract class AbstractProxyInvocationHandler
implements ProxyInvocationH
return this.order;
}
+ @Override
+ public void setNextProxyInvocationHandler(ProxyInvocationHandler next) {
+ this.nextInvocationHandlerChain = next;
+ }
}
diff --git
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
index 03f618ab51..ac942636df 100644
---
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
+++
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
@@ -16,6 +16,15 @@
*/
package org.apache.seata.integration.tx.api.interceptor.handler;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.LinkedHashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import com.google.common.eventbus.Subscribe;
import org.apache.seata.common.exception.ShouldNeverHappenException;
import org.apache.seata.common.thread.NamedThreadFactory;
@@ -32,6 +41,7 @@ import
org.apache.seata.core.exception.TransactionExceptionCode;
import org.apache.seata.core.model.GlobalLockConfig;
import org.apache.seata.integration.tx.api.annotation.AspectTransactional;
import org.apache.seata.integration.tx.api.event.DegradeCheckEvent;
+import org.apache.seata.integration.tx.api.interceptor.InvocationHandlerType;
import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
import
org.apache.seata.integration.tx.api.interceptor.SeataInterceptorPosition;
import org.apache.seata.integration.tx.api.util.ClassUtils;
@@ -51,15 +61,6 @@ import org.apache.seata.tm.api.transaction.TransactionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.LinkedHashSet;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
import static
org.apache.seata.common.DefaultValues.DEFAULT_DISABLE_GLOBAL_TRANSACTION;
import static
org.apache.seata.common.DefaultValues.DEFAULT_GLOBAL_TRANSACTION_TIMEOUT;
import static org.apache.seata.common.DefaultValues.DEFAULT_TM_DEGRADE_CHECK;
@@ -410,4 +411,9 @@ public class GlobalTransactionalInterceptorHandler extends
AbstractProxyInvocati
return SeataInterceptorPosition.BeforeTransaction;
}
+
+ @Override
+ public String type() {
+ return InvocationHandlerType.GlobalTransactional.name();
+ }
}
diff --git
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/ProxyInvocationHandler.java
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/ProxyInvocationHandler.java
index 8238d8526b..1dbe24a61d 100644
---
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/ProxyInvocationHandler.java
+++
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/handler/ProxyInvocationHandler.java
@@ -31,4 +31,11 @@ public interface ProxyInvocationHandler extends
SeataInterceptor {
SeataInterceptorPosition getPosition();
+ String type();
+
+ default int order() {
+ return 0;
+ }
+
+ void setNextProxyInvocationHandler(ProxyInvocationHandler next);
}
diff --git
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
index 2827f9dc7d..c93574e818 100644
---
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
+++
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
@@ -16,13 +16,17 @@
*/
package org.apache.seata.integration.tx.api.interceptor.parser;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
import org.apache.seata.common.loader.EnhancedServiceLoader;
import org.apache.seata.common.util.CollectionUtils;
import
org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* @author leezongjie
*/
@@ -53,15 +57,46 @@ public class DefaultInterfaceParser implements
InterfaceParser {
}
}
+ /**
+ * Create an interceptor chain that supports adding multiple
interceptors.Create an interceptor chain that supports adding multiple
interceptors.
+ * The entry order of the facets can be specified through {@link
ProxyInvocationHandler # order()}.
+ * It is not allowed to load multiple interceptors of the same type, such
as two-stage annotations for TCC and Saga that cannot exist simultaneously. The
type can be specified through {@link ProxyInvocationHandler # type()}.It is not
allowed to load multiple interceptors of the same type, such as two-stage
annotations for TCC and Saga that cannot exist simultaneously. The type can be
specified through {@link ProxyInvocationHandler # type()}.
+ *
+ * @param target
+ * @param objectName
+ * @return
+ * @throws Exception
+ */
@Override
public ProxyInvocationHandler parserInterfaceToProxy(Object target, String
objectName) throws Exception {
+ List<ProxyInvocationHandler> invocationHandlerList = new ArrayList<>();
+ Set<String> invocationHandlerRepeatCheck = new HashSet<>();
+
for (InterfaceParser interfaceParser : ALL_INTERFACE_PARSERS) {
ProxyInvocationHandler proxyInvocationHandler =
interfaceParser.parserInterfaceToProxy(target, objectName);
if (proxyInvocationHandler != null) {
- return proxyInvocationHandler;
+ if
(!invocationHandlerRepeatCheck.add(proxyInvocationHandler.type())) {
+ throw new RuntimeException("there is already an annotation
of type " + proxyInvocationHandler.type() + " for class: " +
target.getClass().getName());
+ }
+ invocationHandlerList.add(proxyInvocationHandler);
}
}
- return null;
+
+ Collections.sort(invocationHandlerList,
Comparator.comparingInt(ProxyInvocationHandler::order));
+
+ ProxyInvocationHandler first = null;
+ ProxyInvocationHandler last = null;
+ for (ProxyInvocationHandler proxyInvocationHandler :
invocationHandlerList) {
+ if (first == null) {
+ first = proxyInvocationHandler;
+ }
+ if (last != null) {
+ last.setNextProxyInvocationHandler(proxyInvocationHandler);
+ }
+ last = proxyInvocationHandler;
+ }
+
+ return first;
}
@Override
diff --git
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
index beacda7de1..8192ff876b 100644
---
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
+++
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
@@ -19,7 +19,6 @@ package
org.apache.seata.integration.tx.api.interceptor.parser;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
-
import org.apache.seata.common.ConfigurationKeys;
import org.apache.seata.common.util.CollectionUtils;
import org.apache.seata.common.util.ReflectionUtil;
@@ -31,7 +30,6 @@ import org.apache.seata.spring.annotation.GlobalLock;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.apache.seata.tm.api.FailureHandlerHolder;
-
public class GlobalTransactionalInterceptorParser implements InterfaceParser {
protected final Set<String> methodsToProxy = new HashSet<>();
diff --git
a/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
b/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
index ffee8848e4..9b50104c9e 100644
---
a/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
+++
b/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
@@ -21,7 +21,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-
import org.apache.seata.common.Constants;
import org.apache.seata.common.DefaultValues;
import org.apache.seata.common.holder.ObjectHolder;
@@ -31,17 +30,16 @@ import org.apache.seata.core.context.RootContext;
import org.apache.seata.core.model.BranchType;
import org.apache.seata.integration.tx.api.fence.config.CommonFenceConfig;
import
org.apache.seata.integration.tx.api.interceptor.ActionInterceptorHandler;
+import org.apache.seata.integration.tx.api.interceptor.InvocationHandlerType;
import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
import
org.apache.seata.integration.tx.api.interceptor.SeataInterceptorPosition;
import
org.apache.seata.integration.tx.api.interceptor.TwoPhaseBusinessActionParam;
import
org.apache.seata.integration.tx.api.interceptor.handler.AbstractProxyInvocationHandler;
import org.apache.seata.rm.tcc.api.TwoPhaseBusinessAction;
import org.slf4j.MDC;
-
import static
org.apache.seata.common.ConfigurationKeys.TCC_ACTION_INTERCEPTOR_ORDER;
import static org.apache.seata.common.Constants.BEAN_NAME_SPRING_FENCE_CONFIG;
-
public class TccActionInterceptorHandler extends
AbstractProxyInvocationHandler {
private static final int ORDER_NUM =
ConfigurationFactory.getInstance().getInt(TCC_ACTION_INTERCEPTOR_ORDER,
@@ -167,4 +165,13 @@ public class TccActionInterceptorHandler extends
AbstractProxyInvocationHandler
return SeataInterceptorPosition.Any;
}
+ @Override
+ public int order() {
+ return 1;
+ }
+
+ @Override
+ public String type() {
+ return InvocationHandlerType.TwoPhaseAnnotation.name();
+ }
}
diff --git
a/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
b/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
index ffe88d6ad1..740690b19d 100644
---
a/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
+++
b/tcc/src/main/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
@@ -21,7 +21,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
-
import org.apache.seata.common.util.ReflectionUtil;
import
org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
import
org.apache.seata.integration.tx.api.interceptor.parser.DefaultResourceRegisterParser;
@@ -34,7 +33,6 @@ import
org.apache.seata.rm.tcc.interceptor.TccActionInterceptorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class TccActionInterceptorParser implements InterfaceParser {
private static final Logger LOGGER =
LoggerFactory.getLogger(TccActionInterceptorParser.class);
diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/BranchSessionMock.java
b/tcc/src/test/java/org/apache/seata/rm/tcc/BranchSessionMock.java
new file mode 100644
index 0000000000..7f60557c73
--- /dev/null
+++ b/tcc/src/test/java/org/apache/seata/rm/tcc/BranchSessionMock.java
@@ -0,0 +1,85 @@
+/*
+ * 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.rm.tcc;
+
+import org.apache.seata.core.model.BranchType;
+
+public class BranchSessionMock {
+
+ private String xid;
+
+ private long branchId;
+
+ private String resourceGroupId;
+
+ private String resourceId;
+
+
+ private BranchType branchType;
+
+
+ private String applicationData;
+
+
+ public String getXid() {
+ return xid;
+ }
+
+ public void setXid(String xid) {
+ this.xid = xid;
+ }
+
+ public long getBranchId() {
+ return branchId;
+ }
+
+ public void setBranchId(long branchId) {
+ this.branchId = branchId;
+ }
+
+ public String getResourceGroupId() {
+ return resourceGroupId;
+ }
+
+ public void setResourceGroupId(String resourceGroupId) {
+ this.resourceGroupId = resourceGroupId;
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public BranchType getBranchType() {
+ return branchType;
+ }
+
+ public void setBranchType(BranchType branchType) {
+ this.branchType = branchType;
+ }
+
+ public String getApplicationData() {
+ return applicationData;
+ }
+
+ public void setApplicationData(String applicationData) {
+ this.applicationData = applicationData;
+ }
+}
diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/TccAction.java
b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java
similarity index 56%
copy from tcc/src/test/java/org/apache/seata/rm/tcc/TccAction.java
copy to tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java
index 8f3c29011f..19fe35a8f8 100644
--- a/tcc/src/test/java/org/apache/seata/rm/tcc/TccAction.java
+++ b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java
@@ -17,33 +17,26 @@
package org.apache.seata.rm.tcc;
import org.apache.seata.rm.tcc.api.BusinessActionContext;
-import org.apache.seata.rm.tcc.api.BusinessActionContextParameter;
import org.apache.seata.rm.tcc.api.LocalTCC;
import org.apache.seata.rm.tcc.api.TwoPhaseBusinessAction;
-import java.util.List;
-
/**
* The interface Tcc action.
- *
*/
@LocalTCC
-public interface TccAction {
+public interface NestTccAction {
/**
* Prepare boolean.
*
* @param actionContext the action context
- * @param a the a
- * @param b the b
- * @param tccParam the tcc param
* @return the boolean
*/
- @TwoPhaseBusinessAction(name = "tccActionForTest", commitMethod =
"commit", rollbackMethod = "rollback", commitArgsClasses =
{BusinessActionContext.class, TccParam.class, Integer.class},
rollbackArgsClasses = {BusinessActionContext.class, TccParam.class})
- boolean prepare(BusinessActionContext actionContext,
- @BusinessActionContextParameter("a") int a,
- @BusinessActionContextParameter(paramName = "b", index =
0) List b,
- @BusinessActionContextParameter(isParamInProperty = true)
TccParam tccParam);
+ @TwoPhaseBusinessAction(name = "tccNestActionForTest")
+ boolean prepare(BusinessActionContext actionContext, int count);
+
+ @TwoPhaseBusinessAction(name = "tccNestActionForTest")
+ boolean prepareNestRequiredNew(BusinessActionContext actionContext, int
count);
/**
* Commit boolean.
@@ -51,8 +44,7 @@ public interface TccAction {
* @param actionContext the action context
* @return the boolean
*/
- boolean commit(BusinessActionContext actionContext,
- @BusinessActionContextParameter("tccParam") TccParam param,
@Param("a") Integer a);
+ boolean commit(BusinessActionContext actionContext);
/**
* Rollback boolean.
@@ -60,5 +52,5 @@ public interface TccAction {
* @param actionContext the action context
* @return the boolean
*/
- boolean rollback(BusinessActionContext actionContext,
@BusinessActionContextParameter("tccParam") TccParam param);
+ boolean rollback(BusinessActionContext actionContext);
}
diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/TccActionImpl.java
b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccActionImpl.java
similarity index 50%
copy from tcc/src/test/java/org/apache/seata/rm/tcc/TccActionImpl.java
copy to tcc/src/test/java/org/apache/seata/rm/tcc/NestTccActionImpl.java
index d49ad3f6d7..4b34d7534e 100644
--- a/tcc/src/test/java/org/apache/seata/rm/tcc/TccActionImpl.java
+++ b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccActionImpl.java
@@ -16,34 +16,47 @@
*/
package org.apache.seata.rm.tcc;
+
import org.apache.seata.rm.tcc.api.BusinessActionContext;
-import org.apache.seata.rm.tcc.api.BusinessActionContextParameter;
+import org.apache.seata.spring.annotation.GlobalTransactional;
+import org.apache.seata.tm.api.transaction.Propagation;
-import java.util.List;
-/**
- * The type Tcc action.
- *
- */
-public class TccActionImpl implements TccAction {
+public class NestTccActionImpl implements NestTccAction {
+
+ private TccAction tccAction;
+ private boolean isCommit;
@Override
- public boolean prepare(BusinessActionContext actionContext,
- int a,
- List b,
- TccParam TccParam ) {
- return true;
+ @GlobalTransactional()
+ public boolean prepare(BusinessActionContext actionContext, int count) {
+ tccAction.prepare(actionContext);
+ return count > 1;
+ }
+
+ @GlobalTransactional(propagation = Propagation.REQUIRES_NEW)
+ @Override
+ public boolean prepareNestRequiredNew(BusinessActionContext actionContext,
int count) {
+ tccAction.prepare(actionContext);
+ return count > 1;
}
@Override
- public boolean commit(BusinessActionContext actionContext,
- @BusinessActionContextParameter("tccParam") TccParam
param, @Param("a") Integer a) {
+ public boolean commit(BusinessActionContext actionContext) {
+ isCommit = true;
return true;
}
@Override
- public boolean rollback(BusinessActionContext actionContext,
- @BusinessActionContextParameter("tccParam")
TccParam param) {
+ public boolean rollback(BusinessActionContext actionContext) {
return true;
}
+
+ public void setTccAction(TccAction tccAction) {
+ this.tccAction = tccAction;
+ }
+
+ public boolean isCommit() {
+ return isCommit;
+ }
}
diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/TccAction.java
b/tcc/src/test/java/org/apache/seata/rm/tcc/TccAction.java
index 8f3c29011f..ec9ea949cf 100644
--- a/tcc/src/test/java/org/apache/seata/rm/tcc/TccAction.java
+++ b/tcc/src/test/java/org/apache/seata/rm/tcc/TccAction.java
@@ -21,11 +21,8 @@ import
org.apache.seata.rm.tcc.api.BusinessActionContextParameter;
import org.apache.seata.rm.tcc.api.LocalTCC;
import org.apache.seata.rm.tcc.api.TwoPhaseBusinessAction;
-import java.util.List;
-
/**
* The interface Tcc action.
- *
*/
@LocalTCC
public interface TccAction {
@@ -34,16 +31,10 @@ public interface TccAction {
* Prepare boolean.
*
* @param actionContext the action context
- * @param a the a
- * @param b the b
- * @param tccParam the tcc param
* @return the boolean
*/
- @TwoPhaseBusinessAction(name = "tccActionForTest", commitMethod =
"commit", rollbackMethod = "rollback", commitArgsClasses =
{BusinessActionContext.class, TccParam.class, Integer.class},
rollbackArgsClasses = {BusinessActionContext.class, TccParam.class})
- boolean prepare(BusinessActionContext actionContext,
- @BusinessActionContextParameter("a") int a,
- @BusinessActionContextParameter(paramName = "b", index =
0) List b,
- @BusinessActionContextParameter(isParamInProperty = true)
TccParam tccParam);
+ @TwoPhaseBusinessAction(name = "tccActionForTest")
+ boolean prepare(BusinessActionContext actionContext);
/**
* Commit boolean.
@@ -51,8 +42,15 @@ public interface TccAction {
* @param actionContext the action context
* @return the boolean
*/
- boolean commit(BusinessActionContext actionContext,
- @BusinessActionContextParameter("tccParam") TccParam param,
@Param("a") Integer a);
+ boolean commit(BusinessActionContext actionContext);
+
+ /**
+ * Commit boolean.
+ *
+ * @param actionContext the action context
+ * @return the boolean
+ */
+ boolean commitWithArg(BusinessActionContext actionContext,
@BusinessActionContextParameter("tccParam") TccParam param, @Param("a") Integer
a);
/**
* Rollback boolean.
@@ -60,5 +58,8 @@ public interface TccAction {
* @param actionContext the action context
* @return the boolean
*/
- boolean rollback(BusinessActionContext actionContext,
@BusinessActionContextParameter("tccParam") TccParam param);
+ boolean rollback(BusinessActionContext actionContext);
+
+ boolean rollbackWithArg(BusinessActionContext actionContext,
@BusinessActionContextParameter("tccParam") TccParam param);
+
}
diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/TccActionImpl.java
b/tcc/src/test/java/org/apache/seata/rm/tcc/TccActionImpl.java
index d49ad3f6d7..d63e67a556 100644
--- a/tcc/src/test/java/org/apache/seata/rm/tcc/TccActionImpl.java
+++ b/tcc/src/test/java/org/apache/seata/rm/tcc/TccActionImpl.java
@@ -17,9 +17,6 @@
package org.apache.seata.rm.tcc;
import org.apache.seata.rm.tcc.api.BusinessActionContext;
-import org.apache.seata.rm.tcc.api.BusinessActionContextParameter;
-
-import java.util.List;
/**
* The type Tcc action.
@@ -27,23 +24,38 @@ import java.util.List;
*/
public class TccActionImpl implements TccAction {
+ private boolean isCommit;
+
+
@Override
- public boolean prepare(BusinessActionContext actionContext,
- int a,
- List b,
- TccParam TccParam ) {
+ public boolean prepare(BusinessActionContext actionContext) {
return true;
}
@Override
- public boolean commit(BusinessActionContext actionContext,
- @BusinessActionContextParameter("tccParam") TccParam
param, @Param("a") Integer a) {
+ public boolean commit(BusinessActionContext actionContext) {
+ isCommit = true;
return true;
}
@Override
- public boolean rollback(BusinessActionContext actionContext,
- @BusinessActionContextParameter("tccParam")
TccParam param) {
+ public boolean commitWithArg(BusinessActionContext actionContext, TccParam
param, Integer a) {
+ return false;
+ }
+
+
+ @Override
+ public boolean rollback(BusinessActionContext actionContext) {
return true;
}
+
+ @Override
+ public boolean rollbackWithArg(BusinessActionContext actionContext,
TccParam param) {
+ return false;
+ }
+
+
+ public boolean isCommit() {
+ return isCommit;
+ }
}
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 79fda99983..0f19353553 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
@@ -16,14 +16,48 @@
*/
package org.apache.seata.rm.tcc.interceptor.parser;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.seata.core.context.RootContext;
+import org.apache.seata.core.exception.TransactionException;
+import org.apache.seata.core.model.BranchType;
+import org.apache.seata.core.model.GlobalStatus;
+import org.apache.seata.core.model.ResourceManager;
+import org.apache.seata.core.model.TransactionManager;
import
org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
+import
org.apache.seata.integration.tx.api.interceptor.parser.DefaultInterfaceParser;
+import org.apache.seata.integration.tx.api.util.ProxyUtil;
+import org.apache.seata.rm.DefaultResourceManager;
+import org.apache.seata.rm.tcc.BranchSessionMock;
+import org.apache.seata.rm.tcc.NestTccAction;
+import org.apache.seata.rm.tcc.NestTccActionImpl;
import org.apache.seata.rm.tcc.NormalTccActionImpl;
+import org.apache.seata.rm.tcc.TCCResourceManager;
+import org.apache.seata.rm.tcc.TccAction;
+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.Assertions;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
class TccActionInterceptorParserTest {
+ @BeforeAll
+ public static void init() throws IOException {
+ System.setProperty("config.type", "file");
+ System.setProperty("config.file.name", "file.conf");
+ System.setProperty("txServiceGroup", "default_tx_group");
+ System.setProperty("service.vgroupMapping.default_tx_group",
"default");
+ }
+
@Test
void parserInterfaceToProxy() {
@@ -38,4 +72,298 @@ class TccActionInterceptorParserTest {
Assertions.assertNotNull(proxyInvocationHandler);
}
+
+
+ @Test
+ public void testNestTcc_should_commit() throws Exception {
+ //given
+ RootContext.unbind();
+ DefaultResourceManager.get();
+ DefaultResourceManager.mockResourceManager(BranchType.TCC,
resourceManager);
+
+ TransactionManagerHolder.set(transactionManager);
+
+ TccActionImpl tccAction = new TccActionImpl();
+ TccAction tccActionProxy = ProxyUtil.createProxy(tccAction);
+ Assertions.assertNotNull(tccActionProxy);
+
+ NestTccActionImpl nestTccAction = new NestTccActionImpl();
+ nestTccAction.setTccAction(tccActionProxy);
+
+ //when
+ ProxyInvocationHandler proxyInvocationHandler =
DefaultInterfaceParser.get().parserInterfaceToProxy(nestTccAction,
nestTccAction.getClass().getName());
+
+ //then
+ Assertions.assertNotNull(proxyInvocationHandler);
+
+
+ //when
+ NestTccAction nestTccActionProxy =
ProxyUtil.createProxy(nestTccAction);
+ //then
+ Assertions.assertNotNull(nestTccActionProxy);
+
+
+ // transaction commit test
+ GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
+
+ try {
+ tx.begin(60000, "testBiz");
+
+ boolean result = nestTccActionProxy.prepare(null, 2);
+
+ Assertions.assertTrue(result);
+
+ if (result) {
+ tx.commit();
+ } else {
+ tx.rollback();
+ }
+ } catch (Exception exx) {
+ tx.rollback();
+ throw exx;
+ }
+
+ Assertions.assertTrue(nestTccAction.isCommit());
+ Assertions.assertTrue(tccAction.isCommit());
+
+ }
+
+
+ @Test
+ public void testNestTcc_should_rollback() throws Exception {
+ //given
+ RootContext.unbind();
+ DefaultResourceManager.get();
+ DefaultResourceManager.mockResourceManager(BranchType.TCC,
resourceManager);
+
+ TransactionManagerHolder.set(transactionManager);
+
+ TccActionImpl tccAction = new TccActionImpl();
+ TccAction tccActionProxy = ProxyUtil.createProxy(tccAction);
+ Assertions.assertNotNull(tccActionProxy);
+
+ NestTccActionImpl nestTccAction = new NestTccActionImpl();
+ nestTccAction.setTccAction(tccActionProxy);
+
+ //when
+ ProxyInvocationHandler proxyInvocationHandler =
DefaultInterfaceParser.get().parserInterfaceToProxy(nestTccAction,
nestTccAction.getClass().getName());
+
+ //then
+ Assertions.assertNotNull(proxyInvocationHandler);
+
+
+ //when
+ NestTccAction nestTccActionProxy =
ProxyUtil.createProxy(nestTccAction);
+ //then
+ Assertions.assertNotNull(nestTccActionProxy);
+
+
+ // transaction commit test
+ GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
+
+ try {
+ tx.begin(60000, "testBiz");
+
+ boolean result = nestTccActionProxy.prepare(null, 1);
+
+ Assertions.assertFalse(result);
+
+ if (result) {
+ tx.commit();
+ } else {
+ tx.rollback();
+ }
+ } catch (Exception exx) {
+ tx.rollback();
+ throw exx;
+ }
+
+ Assertions.assertFalse(nestTccAction.isCommit());
+ Assertions.assertFalse(tccAction.isCommit());
+
+ }
+
+
+ @Test
+ public void testNestTcc_required_new_should_rollback_commit() throws
Exception {
+ //given
+ RootContext.unbind();
+ DefaultResourceManager.get();
+ DefaultResourceManager.mockResourceManager(BranchType.TCC,
resourceManager);
+
+ TransactionManagerHolder.set(transactionManager);
+
+ TccActionImpl tccAction = new TccActionImpl();
+ TccAction tccActionProxy = ProxyUtil.createProxy(tccAction);
+ Assertions.assertNotNull(tccActionProxy);
+
+ NestTccActionImpl nestTccAction = new NestTccActionImpl();
+ nestTccAction.setTccAction(tccActionProxy);
+
+ //when
+ ProxyInvocationHandler proxyInvocationHandler =
DefaultInterfaceParser.get().parserInterfaceToProxy(nestTccAction,
nestTccAction.getClass().getName());
+
+ //then
+ Assertions.assertNotNull(proxyInvocationHandler);
+
+ //when
+ NestTccAction nestTccActionProxy =
ProxyUtil.createProxy(nestTccAction);
+ //then
+ Assertions.assertNotNull(nestTccActionProxy);
+
+
+ // transaction commit test
+ GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
+
+ try {
+ tx.begin(60000, "testBiz");
+
+ boolean result = nestTccActionProxy.prepareNestRequiredNew(null,
1);
+
+ Assertions.assertFalse(result);
+
+ if (result) {
+ tx.commit();
+ } else {
+ tx.rollback();
+ }
+ } catch (Exception exx) {
+ tx.rollback();
+ throw exx;
+ }
+
+ Assertions.assertTrue(nestTccAction.isCommit());
+ Assertions.assertTrue(tccAction.isCommit());
+
+ }
+
+
+
+ @Test
+ public void testNestTcc_required_new_should_both_commit() throws Exception
{
+ //given
+ RootContext.unbind();
+ DefaultResourceManager.get();
+ DefaultResourceManager.mockResourceManager(BranchType.TCC,
resourceManager);
+
+ TransactionManagerHolder.set(transactionManager);
+
+ TccActionImpl tccAction = new TccActionImpl();
+ TccAction tccActionProxy = ProxyUtil.createProxy(tccAction);
+ Assertions.assertNotNull(tccActionProxy);
+
+ NestTccActionImpl nestTccAction = new NestTccActionImpl();
+ nestTccAction.setTccAction(tccActionProxy);
+
+ //when
+ ProxyInvocationHandler proxyInvocationHandler =
DefaultInterfaceParser.get().parserInterfaceToProxy(nestTccAction,
nestTccAction.getClass().getName());
+
+ //then
+ Assertions.assertNotNull(proxyInvocationHandler);
+
+ //when
+ NestTccAction nestTccActionProxy =
ProxyUtil.createProxy(nestTccAction);
+ //then
+ Assertions.assertNotNull(nestTccActionProxy);
+
+
+ // transaction commit test
+ GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
+
+ try {
+ tx.begin(60000, "testBiz");
+
+ boolean result = nestTccActionProxy.prepareNestRequiredNew(null,
2);
+
+ Assertions.assertTrue(result);
+
+ if (result) {
+ tx.commit();
+ } else {
+ tx.rollback();
+ }
+ } catch (Exception exx) {
+ tx.rollback();
+ throw exx;
+ }
+
+ Assertions.assertTrue(nestTccAction.isCommit());
+ Assertions.assertTrue(tccAction.isCommit());
+
+ }
+
+
+
+ private static Map<String, List<BranchSessionMock>> applicationDataMap =
new ConcurrentHashMap<>();
+
+
+ private static TransactionManager transactionManager = new
TransactionManager() {
+ @Override
+ public String begin(String applicationId, String
transactionServiceGroup, String name, int timeout) throws TransactionException {
+ return UUID.randomUUID().toString();
+ }
+
+ @Override
+ public GlobalStatus commit(String xid) throws TransactionException {
+ commitAll(xid);
+ return GlobalStatus.Committed;
+ }
+
+ @Override
+ public GlobalStatus rollback(String xid) throws TransactionException {
+
+ rollbackAll(xid);
+
+ return GlobalStatus.Rollbacked;
+ }
+
+ @Override
+ public GlobalStatus getStatus(String xid) throws TransactionException {
+ return GlobalStatus.Begin;
+ }
+
+ @Override
+ public GlobalStatus globalReport(String xid, GlobalStatus
globalStatus) throws TransactionException {
+ return globalStatus;
+ }
+ };
+
+
+ private static ResourceManager resourceManager = new TCCResourceManager() {
+
+ @Override
+ public Long branchRegister(BranchType branchType, String resourceId,
String clientId, String xid, String applicationData, String lockKeys) throws
TransactionException {
+
+ long branchId = System.currentTimeMillis();
+
+ List<BranchSessionMock> branches =
applicationDataMap.computeIfAbsent(xid, s -> new ArrayList<>());
+ BranchSessionMock branchSessionMock = new BranchSessionMock();
+ branchSessionMock.setXid(xid);
+ branchSessionMock.setBranchType(branchType);
+ branchSessionMock.setResourceId(resourceId);
+ branchSessionMock.setApplicationData(applicationData);
+ branchSessionMock.setBranchId(branchId);
+
+ branches.add(branchSessionMock);
+
+ return branchId;
+ }
+ };
+
+ public static void commitAll(String xid) throws TransactionException {
+
+ List<BranchSessionMock> branches =
applicationDataMap.computeIfAbsent(xid, s -> new ArrayList<>());
+ for (BranchSessionMock branch : branches) {
+ resourceManager.branchCommit(branch.getBranchType(),
branch.getXid(), branch.getBranchId(), branch.getResourceId(),
branch.getApplicationData());
+ }
+ }
+
+ public static void rollbackAll(String xid) throws TransactionException {
+
+ List<BranchSessionMock> branches =
applicationDataMap.computeIfAbsent(xid, s -> new ArrayList<>());
+ for (BranchSessionMock branch : branches) {
+ resourceManager.branchRollback(branch.getBranchType(),
branch.getXid(), branch.getBranchId(), branch.getResourceId(),
branch.getApplicationData());
+ }
+ }
+
}
diff --git
a/tcc/src/test/java/org/apache/seata/rm/tcc/resource/parser/TccRegisterResourceParserTest.java
b/tcc/src/test/java/org/apache/seata/rm/tcc/resource/parser/TccRegisterResourceParserTest.java
index a11e12f8b1..b7f651afae 100644
---
a/tcc/src/test/java/org/apache/seata/rm/tcc/resource/parser/TccRegisterResourceParserTest.java
+++
b/tcc/src/test/java/org/apache/seata/rm/tcc/resource/parser/TccRegisterResourceParserTest.java
@@ -16,13 +16,14 @@
*/
package org.apache.seata.rm.tcc.resource.parser;
+import java.lang.reflect.Method;
+
+import org.apache.seata.rm.tcc.TccAction;
import org.apache.seata.rm.tcc.TccParam;
import org.apache.seata.rm.tcc.api.BusinessActionContext;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-import java.lang.reflect.Method;
-
class TccRegisterResourceParserTest {
@@ -30,14 +31,13 @@ class TccRegisterResourceParserTest {
@Test
public void testGetTwoPhaseArgs() throws Exception {
- Class<?> tccActionImpl =
Class.forName("org.apache.seata.rm.tcc.TccActionImpl");
Class<?>[] argsCommitClasses = new
Class[]{BusinessActionContext.class, TccParam.class, Integer.class};
- Method commitMethod = tccActionImpl.getMethod("commit",
argsCommitClasses);
+ Method commitMethod = TccAction.class.getMethod("commitWithArg",
argsCommitClasses);
Assertions.assertThrows(IllegalArgumentException.class, () -> {
tccRegisterResourceParser.getTwoPhaseArgs(commitMethod,
argsCommitClasses);
});
Class<?>[] argsRollbackClasses = new
Class[]{BusinessActionContext.class, TccParam.class};
- Method rollbackMethod = tccActionImpl.getMethod("rollback",
argsRollbackClasses);
+ Method rollbackMethod = TccAction.class.getMethod("rollbackWithArg",
argsRollbackClasses);
String[] keys =
tccRegisterResourceParser.getTwoPhaseArgs(rollbackMethod, argsRollbackClasses);
Assertions.assertNull(keys[0]);
Assertions.assertEquals("tccParam", keys[1]);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]