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 13a5adad8b optimize: optimized globaltransaction compatibility issues 
(#6366)
13a5adad8b is described below

commit 13a5adad8b3e725d79f0760fdd93366c1e16b540
Author: funkye <jian...@apache.org>
AuthorDate: Mon Mar 4 16:16:15 2024 +0800

    optimize: optimized globaltransaction compatibility issues (#6366)
---
 changes/en-us/2.x.md                               |   1 +
 changes/zh-cn/2.x.md                               |   2 +
 compatible/pom.xml                                 |   6 +
 .../tx/api/interceptor/ActionContextUtil.java      |   1 +
 .../api/interceptor/ActionInterceptorHandler.java  |   1 +
 .../GlobalTransactionalInterceptorHandler.java     | 102 ++++++++--------
 .../GlobalTransactionalInterceptorParser.java      |  19 ++-
 .../seata/integration/tx/api/json/JsonParser.java  |   3 +-
 .../tx/api/remoting/RemotingParser.java            |   1 +
 .../io/seata/tm/api/DefaultFailureHandlerImpl.java | 117 ++++++++++++++++++
 .../io/seata/tm/api/DefaultGlobalTransaction.java  |   4 +
 .../main/java/io/seata/tm/api/FailureHandler.java  |   2 +-
 .../java/io/seata/tm/api/GlobalTransaction.java    |   3 +-
 ...ation.tx.api.interceptor.parser.InterfaceParser |   1 +
 .../tx/api/interceptor/parser/Business.java}       |  13 +-
 .../tx/api/interceptor/parser/BusinessImpl.java}   |  16 ++-
 .../GlobalTransactionalInterceptorParserTest.java  |  20 ++-
 .../tm/api/DefaultFailureHandlerImplTest.java      | 136 +++++++++++++++++++++
 .../tm/api/transaction/MyRuntimeException.java}    |   8 +-
 compatible/src/test/resources/file.conf            |  25 ++++
 compatible/src/test/resources/registry.conf        |  34 ++++++
 .../handler/AbstractProxyInvocationHandler.java    |   8 ++
 .../GlobalTransactionalInterceptorHandler.java     |  61 ++++-----
 .../GlobalTransactionalInterceptorParser.java      |   6 +-
 .../tx/api/interceptor/parser/InterfaceParser.java |   1 -
 .../GlobalTransactionalInterceptorParserTest.java  |   2 +-
 .../org/apache/seata/tm/api/BaseTransaction.java   |   4 +-
 .../seata/tm/api/DefaultFailureHandlerImpl.java    |   2 +-
 .../org/apache/seata/tm/api/FailureHandler.java    |  10 +-
 .../apache/seata/tm/api/FailureHandlerHolder.java  |   6 +-
 .../org/apache/seata/tm/api/GlobalTransaction.java |   2 +-
 .../org/apache/seata/tm/api/TMFailureHandler.java  |   9 +-
 32 files changed, 510 insertions(+), 116 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 2df25a629d..6d9a0631d2 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -100,6 +100,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#6345](https://github.com/apache/incubator-seata/pull/6345)] compatible 
with tcc module
 - [[#6356](https://github.com/apache/incubator-seata/pull/6356)] remove 
authentication from the health check page
 - [[#6360](https://github.com/apache/incubator-seata/pull/6360)] optimize 401 
issues for some links
+- [[#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`
 
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 6099f3ae33..29c9654fac 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -104,10 +104,12 @@
 - [[#6356](https://github.com/apache/incubator-seata/pull/6356)] 去除健康检查页面的鉴权
 - [[#6360](https://github.com/apache/incubator-seata/pull/6360)] 优化部分链接 401 的问题
 - [[#6350](https://github.com/apache/incubator-seata/pull/6350)] 移除 
enableDegrade 配置
+- [[#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代理
 
 
+
 ### refactor:
 - [[#6269](https://github.com/apache/incubator-seata/pull/6269)] 统一Seata异常规范
 
diff --git a/compatible/pom.xml b/compatible/pom.xml
index f170f13bd9..5d4de46dbb 100644
--- a/compatible/pom.xml
+++ b/compatible/pom.xml
@@ -111,6 +111,12 @@
             <version>1.27.1</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>5.8.2</version>
+            <scope>test</scope>
+           </dependency>
         <dependency>
             <groupId>org.apache.seata</groupId>
             <artifactId>seata-tcc</artifactId>
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionContextUtil.java
 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionContextUtil.java
index 478fc22204..3fefc5e685 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionContextUtil.java
+++ 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionContextUtil.java
@@ -32,6 +32,7 @@ import java.util.Map;
 /**
  * Extracting TCC Context from Method
  */
+@Deprecated
 public final class ActionContextUtil {
 
     private ActionContextUtil() {
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandler.java
 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandler.java
index 161188cd03..a21b897a49 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandler.java
+++ 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandler.java
@@ -27,6 +27,7 @@ import java.util.Map;
 /**
  * Handler the Tx Participant Aspect : Setting Context, Creating Branch Record
  */
+@Deprecated
 public class ActionInterceptorHandler extends 
org.apache.seata.integration.tx.api.interceptor.ActionInterceptorHandler {
 
 
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
index 2882ec1fa9..7dd3a32f81 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
+++ 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/handler/GlobalTransactionalInterceptorHandler.java
@@ -18,78 +18,78 @@ package io.seata.integration.tx.api.interceptor.handler;
 
 import io.seata.spring.annotation.GlobalLock;
 import io.seata.spring.annotation.GlobalTransactional;
-import io.seata.tm.api.FailureHandler;
+import org.apache.seata.common.LockStrategyMode;
 import org.apache.seata.core.model.GlobalLockConfig;
 import org.apache.seata.integration.tx.api.annotation.AspectTransactional;
-import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
-import org.apache.seata.integration.tx.api.util.ClassUtils;
-import org.apache.seata.rm.GlobalLockExecutor;
+import org.apache.seata.tm.api.transaction.Propagation;
 
 import java.lang.reflect.Method;
+import java.util.Objects;
 import java.util.Set;
 
 /**
  * The type Global transactional interceptor handler.
  */
+@Deprecated
 public class GlobalTransactionalInterceptorHandler extends 
org.apache.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler
 {
 
-
-    public GlobalTransactionalInterceptorHandler(FailureHandler 
failureHandler, Set<String> methodsToProxy) {
+    public 
GlobalTransactionalInterceptorHandler(org.apache.seata.tm.api.FailureHandler 
failureHandler, Set<String> methodsToProxy) {
         super(failureHandler, methodsToProxy);
     }
 
-    public GlobalTransactionalInterceptorHandler(FailureHandler 
failureHandler, Set<String> methodsToProxy, AspectTransactional 
aspectTransactional) {
+    public 
GlobalTransactionalInterceptorHandler(org.apache.seata.tm.api.FailureHandler 
failureHandler, Set<String> methodsToProxy,
+        AspectTransactional aspectTransactional) {
         super(failureHandler, methodsToProxy, aspectTransactional);
     }
 
     @Override
-    protected Object doInvoke(InvocationWrapper invocation) throws Throwable {
-        Class<?> targetClass = invocation.getTarget().getClass();
-        Method specificMethod = 
ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
-        if (specificMethod != null && 
!specificMethod.getDeclaringClass().equals(Object.class)) {
-            final GlobalTransactional globalTransactionalAnnotation = 
getAnnotation(specificMethod, targetClass, GlobalTransactional.class);
-            final GlobalLock globalLockAnnotation = 
getAnnotation(specificMethod, targetClass, GlobalLock.class);
-            boolean localDisable = disable || (ATOMIC_DEGRADE_CHECK.get() && 
degradeNum >= degradeCheckAllowTimes);
-            if (!localDisable) {
-                if (globalTransactionalAnnotation != null || 
this.aspectTransactional != null) {
-                    AspectTransactional transactional;
-                    if (globalTransactionalAnnotation != null) {
-                        transactional = new 
AspectTransactional(globalTransactionalAnnotation.timeoutMills(),
-                                globalTransactionalAnnotation.name(), 
globalTransactionalAnnotation.rollbackFor(),
-                                
globalTransactionalAnnotation.rollbackForClassName(),
-                                globalTransactionalAnnotation.noRollbackFor(),
-                                
globalTransactionalAnnotation.noRollbackForClassName(),
-                                
org.apache.seata.tm.api.transaction.Propagation.valueOf(globalTransactionalAnnotation.propagation().name()),
-                                
globalTransactionalAnnotation.lockRetryInterval(),
-                                globalTransactionalAnnotation.lockRetryTimes(),
-                                
org.apache.seata.common.LockStrategyMode.valueOf(globalTransactionalAnnotation.lockStrategyMode().name()));
-                    } else {
-                        transactional = this.aspectTransactional;
-                    }
-                    return handleGlobalTransaction(invocation, transactional);
-                } else if (globalLockAnnotation != null) {
-                    return handleGlobalLock(invocation, globalLockAnnotation);
-                }
-            }
+    public GlobalLockConfig getGlobalLockConfig(Method method, Class<?> 
targetClass) {
+        final GlobalLock globalLockAnno = getAnnotation(method, targetClass, 
GlobalLock.class);
+        if (globalLockAnno != null) {
+            GlobalLockConfig config = new GlobalLockConfig();
+            config.setLockRetryInterval(globalLockAnno.lockRetryInterval());
+            config.setLockRetryTimes(globalLockAnno.lockRetryTimes());
+            return config;
+        } else {
+            return null;
         }
-        return invocation.proceed();
     }
 
+    @Override
+    public AspectTransactional getAspectTransactional(Method method, Class<?> 
targetClass) {
+        final GlobalTransactional globalTransactionalAnnotation =
+            getAnnotation(method, targetClass, GlobalTransactional.class);
+        return globalTransactionalAnnotation != null ? new AspectTransactional(
+            globalTransactionalAnnotation.timeoutMills(), 
globalTransactionalAnnotation.name(),
+            globalTransactionalAnnotation.rollbackFor(), 
globalTransactionalAnnotation.rollbackForClassName(),
+            globalTransactionalAnnotation.noRollbackFor(), 
globalTransactionalAnnotation.noRollbackForClassName(),
+            
propagation2ApacheSeataPropagation(globalTransactionalAnnotation.propagation()),
+            globalTransactionalAnnotation.lockRetryInterval(), 
globalTransactionalAnnotation.lockRetryTimes(),
+            
lockStrategyMode2ApacheSeataLockStrategyMode(globalTransactionalAnnotation.lockStrategyMode()))
 : null;
+    }
 
-    private Object handleGlobalLock(final InvocationWrapper methodInvocation, 
final GlobalLock globalLockAnno) throws Throwable {
-        return globalLockTemplate.execute(new GlobalLockExecutor() {
-            @Override
-            public Object execute() throws Throwable {
-                return methodInvocation.proceed();
-            }
+    private Propagation 
propagation2ApacheSeataPropagation(io.seata.tm.api.transaction.Propagation 
propagation){
+        switch (propagation) {
+            case NEVER:
+                return Propagation.NEVER;
+            case REQUIRES_NEW:
+                return Propagation.REQUIRES_NEW;
+            case NOT_SUPPORTED:
+                return Propagation.NOT_SUPPORTED;
+            case SUPPORTS:
+                return Propagation.SUPPORTS;
+            case MANDATORY:
+                return Propagation.MANDATORY;
+            default:
+                return Propagation.REQUIRED;
+        }
+    }
 
-            @Override
-            public GlobalLockConfig getGlobalLockConfig() {
-                GlobalLockConfig config = new GlobalLockConfig();
-                
config.setLockRetryInterval(globalLockAnno.lockRetryInterval());
-                config.setLockRetryTimes(globalLockAnno.lockRetryTimes());
-                return config;
-            }
-        });
+    private LockStrategyMode 
lockStrategyMode2ApacheSeataLockStrategyMode(io.seata.common.LockStrategyMode 
lockStrategyMode){
+           if (Objects.requireNonNull(lockStrategyMode) == 
io.seata.common.LockStrategyMode.OPTIMISTIC) {
+                   return LockStrategyMode.OPTIMISTIC;
+           }
+           return LockStrategyMode.PESSIMISTIC;
     }
-}
+
+}
\ No newline at end of file
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
index 485034e6e3..974fd66eb4 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
+++ 
b/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
@@ -16,12 +16,16 @@
  */
 package io.seata.integration.tx.api.interceptor.parser;
 
+import 
io.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler;
 import io.seata.spring.annotation.GlobalLock;
 import io.seata.spring.annotation.GlobalTransactional;
 import org.apache.seata.common.util.CollectionUtils;
+import 
org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
+import org.apache.seata.tm.api.FailureHandlerHolder;
 
 import java.lang.reflect.Method;
 
+@Deprecated
 public class GlobalTransactionalInterceptorParser extends 
org.apache.seata.integration.tx.api.interceptor.parser.GlobalTransactionalInterceptorParser
 {
 
     @Override
@@ -33,24 +37,21 @@ public class GlobalTransactionalInterceptorParser extends 
org.apache.seata.integ
                     continue;
                 }
                 GlobalTransactional trxAnnoOld = 
clazz.getAnnotation(GlobalTransactional.class);
-                org.apache.seata.spring.annotation.GlobalTransactional 
trxAnnoNew = 
clazz.getAnnotation(org.apache.seata.spring.annotation.GlobalTransactional.class);
 
-                if (trxAnnoOld != null || trxAnnoNew != null) {
+                if (trxAnnoOld != null) {
                     return true;
                 }
                 Method[] methods = clazz.getMethods();
                 for (Method method : methods) {
                     trxAnnoOld = 
method.getAnnotation(GlobalTransactional.class);
-                    trxAnnoNew = 
method.getAnnotation(org.apache.seata.spring.annotation.GlobalTransactional.class);
-                    if (trxAnnoOld != null || trxAnnoNew != null) {
+                    if (trxAnnoOld != null) {
                         methodsToProxy.add(method.getName());
                         result = true;
                     }
 
                     GlobalLock lockAnnoOld = 
method.getAnnotation(GlobalLock.class);
-                    org.apache.seata.spring.annotation.GlobalLock lockAnnoNew 
= method.getAnnotation(org.apache.seata.spring.annotation.GlobalLock.class);
 
-                    if (lockAnnoOld != null || lockAnnoNew != null) {
+                    if (lockAnnoOld != null) {
                         methodsToProxy.add(method.getName());
                         result = true;
                     }
@@ -59,4 +60,10 @@ public class GlobalTransactionalInterceptorParser extends 
org.apache.seata.integ
         }
         return result;
     }
+
+    @Override
+    public ProxyInvocationHandler createProxyInvocationHandler(){
+        return new 
GlobalTransactionalInterceptorHandler(FailureHandlerHolder.getFailureHandler(), 
methodsToProxy);
+    }
+
 }
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/json/JsonParser.java 
b/compatible/src/main/java/io/seata/integration/tx/api/json/JsonParser.java
index e7ac74158d..5a4395bbef 100644
--- a/compatible/src/main/java/io/seata/integration/tx/api/json/JsonParser.java
+++ b/compatible/src/main/java/io/seata/integration/tx/api/json/JsonParser.java
@@ -16,7 +16,6 @@
  */
 package io.seata.integration.tx.api.json;
 
-
-
+@Deprecated
 public interface JsonParser extends 
org.apache.seata.integration.tx.api.json.JsonParser {
 }
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
 
b/compatible/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
index 9978a706ab..92505200e8 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
+++ 
b/compatible/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
@@ -21,5 +21,6 @@ package io.seata.integration.tx.api.remoting;
  * extract remoting bean info
  *
  */
+@Deprecated
 public interface RemotingParser extends 
org.apache.seata.integration.tx.api.remoting.RemotingParser {
 }
diff --git 
a/compatible/src/main/java/io/seata/tm/api/DefaultFailureHandlerImpl.java 
b/compatible/src/main/java/io/seata/tm/api/DefaultFailureHandlerImpl.java
new file mode 100644
index 0000000000..db18a8fd58
--- /dev/null
+++ b/compatible/src/main/java/io/seata/tm/api/DefaultFailureHandlerImpl.java
@@ -0,0 +1,117 @@
+/*
+ * 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 io.seata.tm.api;
+
+import java.util.concurrent.TimeUnit;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timeout;
+import io.netty.util.TimerTask;
+import io.seata.core.model.GlobalStatus;
+import org.apache.seata.common.thread.NamedThreadFactory;
+import org.apache.seata.core.exception.TransactionException;
+import org.apache.seata.core.logger.StackTraceLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The type Default failure handler.
+ *
+ */
+public class DefaultFailureHandlerImpl implements FailureHandler {
+
+       private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultFailureHandlerImpl.class);
+
+       /**
+        * Retry 1 hours by default
+        */
+       private static final int RETRY_MAX_TIMES = 6 * 60;
+
+       private static final long SCHEDULE_INTERVAL_SECONDS = 10;
+
+       private static final long TICK_DURATION = 1;
+
+       private static final int TICKS_PER_WHEEL = 8;
+
+       private static final HashedWheelTimer TIMER = new HashedWheelTimer(
+               new NamedThreadFactory("failedTransactionRetry", 1),
+               TICK_DURATION, TimeUnit.SECONDS, TICKS_PER_WHEEL);
+
+       @Override
+       public void onBeginFailure(GlobalTransaction tx, Throwable cause) {
+               LOGGER.warn("Failed to begin transaction. ", cause);
+       }
+
+       @Override
+       public void onCommitFailure(GlobalTransaction tx, Throwable cause) {
+               LOGGER.warn("Failed to commit transaction[" + tx.getXid() + 
"]", cause);
+               TIMER.newTimeout(new 
DefaultFailureHandlerImpl.CheckTimerTask(tx, GlobalStatus.Committed), 
SCHEDULE_INTERVAL_SECONDS, TimeUnit.SECONDS);
+       }
+
+       @Override
+       public void onRollbackFailure(GlobalTransaction tx, Throwable 
originalException) {
+               LOGGER.warn("Failed to rollback transaction[" + tx.getXid() + 
"]", originalException);
+               TIMER.newTimeout(new 
DefaultFailureHandlerImpl.CheckTimerTask(tx, GlobalStatus.Rollbacked), 
SCHEDULE_INTERVAL_SECONDS, TimeUnit.SECONDS);
+       }
+
+       @Override
+       public void onRollbacking(GlobalTransaction tx, Throwable 
originalException) {
+               StackTraceLogger.warn(LOGGER, originalException, "Retrying to 
rollback transaction[{}]", new String[] {tx.getXid()});
+               TIMER.newTimeout(new 
DefaultFailureHandlerImpl.CheckTimerTask(tx, GlobalStatus.RollbackRetrying), 
SCHEDULE_INTERVAL_SECONDS,
+                       TimeUnit.SECONDS);
+       }
+
+       protected class CheckTimerTask implements TimerTask {
+
+               private final GlobalTransaction tx;
+
+               private final GlobalStatus required;
+
+               private int count = 0;
+
+               private boolean isStopped = false;
+
+               protected CheckTimerTask(final GlobalTransaction tx, 
GlobalStatus required) {
+                       this.tx = tx;
+                       this.required = required;
+               }
+
+               @Override
+               public void run(Timeout timeout) throws Exception {
+                       if (!isStopped) {
+                               if (++count > RETRY_MAX_TIMES) {
+                                       LOGGER.error("transaction [{}] retry 
fetch status times exceed the limit [{} times]", tx.getXid(), RETRY_MAX_TIMES);
+                                       return;
+                               }
+                               isStopped = shouldStop(tx, required);
+                               TIMER.newTimeout(this, 
SCHEDULE_INTERVAL_SECONDS, TimeUnit.SECONDS);
+                       }
+               }
+       }
+
+       private boolean shouldStop(final GlobalTransaction tx, GlobalStatus 
required) {
+               try {
+                       GlobalStatus status = tx.getStatus();
+                       LOGGER.info("transaction [{}] current status is [{}]", 
tx.getXid(), status);
+                       if (status == required || status == 
GlobalStatus.Finished) {
+                               return true;
+                       }
+               } catch (TransactionException e) {
+                       LOGGER.error("fetch GlobalTransaction status error", e);
+               }
+               return false;
+       }
+}
diff --git 
a/compatible/src/main/java/io/seata/tm/api/DefaultGlobalTransaction.java 
b/compatible/src/main/java/io/seata/tm/api/DefaultGlobalTransaction.java
index 31a72c91b4..1a35047ed5 100644
--- a/compatible/src/main/java/io/seata/tm/api/DefaultGlobalTransaction.java
+++ b/compatible/src/main/java/io/seata/tm/api/DefaultGlobalTransaction.java
@@ -167,4 +167,8 @@ public class DefaultGlobalTransaction implements 
GlobalTransaction {
     public long getCreateTime() {
         return this.instance.getCreateTime();
     }
+
+    public org.apache.seata.tm.api.DefaultGlobalTransaction getInstance() {
+        return instance;
+    }
 }
diff --git a/compatible/src/main/java/io/seata/tm/api/FailureHandler.java 
b/compatible/src/main/java/io/seata/tm/api/FailureHandler.java
index 5ff6615201..2058deb188 100644
--- a/compatible/src/main/java/io/seata/tm/api/FailureHandler.java
+++ b/compatible/src/main/java/io/seata/tm/api/FailureHandler.java
@@ -16,5 +16,5 @@
  */
 package io.seata.tm.api;
 
-public interface FailureHandler extends org.apache.seata.tm.api.FailureHandler 
{
+public interface FailureHandler extends 
org.apache.seata.tm.api.FailureHandler<GlobalTransaction> {
 }
diff --git a/compatible/src/main/java/io/seata/tm/api/GlobalTransaction.java 
b/compatible/src/main/java/io/seata/tm/api/GlobalTransaction.java
index 2184f02b71..ef0f29be7c 100644
--- a/compatible/src/main/java/io/seata/tm/api/GlobalTransaction.java
+++ b/compatible/src/main/java/io/seata/tm/api/GlobalTransaction.java
@@ -19,11 +19,12 @@ package io.seata.tm.api;
 import io.seata.core.exception.TransactionException;
 import io.seata.core.model.GlobalStatus;
 import io.seata.tm.api.transaction.SuspendedResourcesHolder;
+import org.apache.seata.tm.api.BaseTransaction;
 
 /**
  * Global transaction.
  */
-public interface GlobalTransaction {
+public interface GlobalTransaction extends BaseTransaction {
 
     /**
      * Begin a new global transaction with default timeout and name.
diff --git 
a/compatible/src/main/resources/META-INF/services/org.apache.seata.integration.tx.api.interceptor.parser.InterfaceParser
 
b/compatible/src/main/resources/META-INF/services/org.apache.seata.integration.tx.api.interceptor.parser.InterfaceParser
new file mode 100644
index 0000000000..b9e1043dc3
--- /dev/null
+++ 
b/compatible/src/main/resources/META-INF/services/org.apache.seata.integration.tx.api.interceptor.parser.InterfaceParser
@@ -0,0 +1 @@
+io.seata.integration.tx.api.interceptor.parser.GlobalTransactionalInterceptorParser
\ No newline at end of file
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/RegisterResourceParser.java
 
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/Business.java
similarity index 81%
rename from 
compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/RegisterResourceParser.java
rename to 
compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/Business.java
index c1c8b67907..dec0026815 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/RegisterResourceParser.java
+++ 
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/Business.java
@@ -16,6 +16,15 @@
  */
 package io.seata.integration.tx.api.interceptor.parser;
 
-public interface RegisterResourceParser extends 
org.apache.seata.integration.tx.api.interceptor.parser.RegisterResourceParser {
-
+/**
+ * The interface Business.
+ */
+public interface Business {
+    /**
+     * Do biz string.
+     *
+     * @param msg the msg
+     * @return the string
+     */
+    String doBiz(String msg);
 }
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
 
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/BusinessImpl.java
similarity index 64%
copy from 
compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
copy to 
compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/BusinessImpl.java
index 2381924a07..2cc312b833 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
+++ 
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/BusinessImpl.java
@@ -16,6 +16,20 @@
  */
 package io.seata.integration.tx.api.interceptor.parser;
 
+import io.seata.spring.annotation.GlobalTransactional;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public interface InterfaceParser extends 
org.apache.seata.integration.tx.api.interceptor.parser.InterfaceParser {
+/**
+ * The type Business.
+ */
+@GlobalTransactional(timeoutMills = 300000, name = "busi-doBiz")
+public class BusinessImpl implements Business {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(BusinessImpl.class);
+
+    @Override
+    public String doBiz(String msg) {
+        LOGGER.info("Business doBiz");
+        return "hello " + msg;
+    }
 }
diff --git 
a/integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
 
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
similarity index 59%
copy from 
integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
copy to 
compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
index a829b4df15..7ea7712c74 100644
--- 
a/integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
+++ 
b/compatible/src/test/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
@@ -14,14 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.seata.integration.tx.api.interceptor.parser;
+package io.seata.integration.tx.api.interceptor.parser;
 
+import 
io.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler;
+import io.seata.tm.api.DefaultFailureHandlerImpl;
+import io.seata.tm.api.FailureHandler;
 import 
org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
+import org.apache.seata.integration.tx.api.util.ProxyUtil;
+import org.apache.seata.tm.api.FailureHandlerHolder;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-
-class GlobalTransactionalInterceptorParserTest {
+public class GlobalTransactionalInterceptorParserTest {
 
     @Test
     void parserInterfaceToProxy() throws Exception {
@@ -29,7 +33,11 @@ class GlobalTransactionalInterceptorParserTest {
         //given
         BusinessImpl business = new BusinessImpl();
 
-        GlobalTransactionalInterceptorParser 
globalTransactionalInterceptorParser = new 
GlobalTransactionalInterceptorParser();
+        GlobalTransactionalInterceptorParser
+               globalTransactionalInterceptorParser = new 
GlobalTransactionalInterceptorParser();
+        FailureHandler failureHandler = new DefaultFailureHandlerImpl();
+
+        FailureHandlerHolder.setFailureHandler(failureHandler);
 
         //when
         ProxyInvocationHandler proxyInvocationHandler = 
globalTransactionalInterceptorParser.parserInterfaceToProxy(business, 
business.getClass().getName());
@@ -37,6 +45,10 @@ class GlobalTransactionalInterceptorParserTest {
         //then
         Assertions.assertNotNull(proxyInvocationHandler);
 
+        Assertions.assertEquals(proxyInvocationHandler.getClass(), 
GlobalTransactionalInterceptorHandler.class);
+
+        Business  businessProxy = ProxyUtil.createProxy(business);
+        Assertions.assertNotEquals(businessProxy, business);
 
     }
 }
diff --git 
a/compatible/src/test/java/io/seata/tm/api/DefaultFailureHandlerImplTest.java 
b/compatible/src/test/java/io/seata/tm/api/DefaultFailureHandlerImplTest.java
new file mode 100644
index 0000000000..5889398498
--- /dev/null
+++ 
b/compatible/src/test/java/io/seata/tm/api/DefaultFailureHandlerImplTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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 io.seata.tm.api;
+
+import java.lang.reflect.Field;
+
+import io.seata.core.context.RootContext;
+import io.seata.tm.api.transaction.MyRuntimeException;
+import org.apache.seata.core.exception.TransactionException;
+import org.apache.seata.core.model.GlobalStatus;
+import org.apache.seata.core.model.TransactionManager;
+import org.apache.seata.tm.TransactionManagerHolder;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.netty.util.HashedWheelTimer;
+
+class DefaultFailureHandlerImplTest {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultFailureHandlerImplTest.class);
+
+    private static final String DEFAULT_XID = "1234567890";
+    private static GlobalStatus globalStatus = GlobalStatus.Begin;
+
+    @BeforeAll
+    public static void init() {
+
+        TransactionManagerHolder.set(new TransactionManager() {
+            @Override
+            public String begin(String applicationId, String 
transactionServiceGroup, String name, int timeout)
+                    throws TransactionException {
+                return DEFAULT_XID;
+            }
+
+            @Override
+            public GlobalStatus commit(String xid) throws TransactionException 
{
+                return GlobalStatus.Committed;
+            }
+
+            @Override
+            public GlobalStatus rollback(String xid) throws 
TransactionException {
+                return GlobalStatus.Rollbacked;
+            }
+
+            @Override
+            public GlobalStatus getStatus(String xid) throws 
TransactionException {
+                return globalStatus;
+            }
+
+            @Override
+            public GlobalStatus globalReport(String xid, GlobalStatus 
globalStatus) throws TransactionException {
+                return globalStatus;
+            }
+        });
+    }
+
+    @Test
+    void onBeginFailure() {
+        RootContext.bind(DEFAULT_XID);
+        DefaultGlobalTransaction tx = 
(DefaultGlobalTransaction)GlobalTransactionContext.getCurrentOrCreate();
+        FailureHandler failureHandler = new DefaultFailureHandlerImpl();
+        failureHandler.onBeginFailure(tx, new 
MyRuntimeException("").getCause());
+    }
+
+    @Test
+    void onCommitFailure() throws Exception{
+
+        RootContext.bind(DEFAULT_XID);
+        DefaultGlobalTransaction tx = 
(DefaultGlobalTransaction)GlobalTransactionContext.getCurrentOrCreate();
+        FailureHandler failureHandler = new DefaultFailureHandlerImpl();
+        failureHandler.onCommitFailure(tx, new 
MyRuntimeException("").getCause());
+
+        // get timer
+        Class<?> c = 
Class.forName("io.seata.tm.api.DefaultFailureHandlerImpl");
+        Field field = c.getSuperclass().getDeclaredField("TIMER");
+        field.setAccessible(true);
+        HashedWheelTimer timer = (HashedWheelTimer) field.get(failureHandler);
+        // assert timer pendingCount: first time is 1
+        Long pendingTimeout = timer.pendingTimeouts();
+        Assertions.assertEquals(pendingTimeout,1L);
+        //set globalStatus
+        globalStatus= GlobalStatus.Committed;
+        Thread.sleep(25*1000L);
+        pendingTimeout = timer.pendingTimeouts();
+        LOGGER.info("pendingTimeout {}" ,pendingTimeout);
+        //all timer is done
+        Assertions.assertEquals(pendingTimeout,0L);
+    }
+
+    @Test
+    void onRollbackFailure() throws Exception {
+
+
+        RootContext.bind(DEFAULT_XID);
+        DefaultGlobalTransaction tx = 
(DefaultGlobalTransaction)GlobalTransactionContext.getCurrentOrCreate();
+        FailureHandler failureHandler = new DefaultFailureHandlerImpl();
+
+        failureHandler.onRollbackFailure(tx, new 
MyRuntimeException("").getCause());
+
+        // get timer
+        Class<?> c = 
Class.forName("io.seata.tm.api.DefaultFailureHandlerImpl");
+        Field field = c.getSuperclass().getDeclaredField("TIMER");
+        field.setAccessible(true);
+        HashedWheelTimer timer = (HashedWheelTimer) field.get(failureHandler);
+        // assert timer pendingCount: first time is 1
+        Long pendingTimeout = timer.pendingTimeouts();
+        Assertions.assertEquals(pendingTimeout,1L);
+        //set globalStatus
+        globalStatus= GlobalStatus.Rollbacked;
+        Thread.sleep(25*1000L);
+        pendingTimeout = timer.pendingTimeouts();
+        LOGGER.info("pendingTimeout {}" ,pendingTimeout);
+        //all timer is done
+        Assertions.assertEquals(pendingTimeout,0L);
+
+
+    }
+
+
+}
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
 b/compatible/src/test/java/io/seata/tm/api/transaction/MyRuntimeException.java
similarity index 82%
rename from 
compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
rename to 
compatible/src/test/java/io/seata/tm/api/transaction/MyRuntimeException.java
index 2381924a07..51954a24b2 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
+++ 
b/compatible/src/test/java/io/seata/tm/api/transaction/MyRuntimeException.java
@@ -14,8 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.seata.integration.tx.api.interceptor.parser;
+package io.seata.tm.api.transaction;
 
 
-public interface InterfaceParser extends 
org.apache.seata.integration.tx.api.interceptor.parser.InterfaceParser {
+public class MyRuntimeException extends RuntimeException {
+
+    public MyRuntimeException(String msg) {
+        super(msg);
+    }
 }
diff --git a/compatible/src/test/resources/file.conf 
b/compatible/src/test/resources/file.conf
new file mode 100644
index 0000000000..46c3e0401c
--- /dev/null
+++ b/compatible/src/test/resources/file.conf
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+service {
+  #transaction service group mapping
+  vgroupMapping.default_tx_group = "default"
+  #only support when registry.type=file, please don't set multiple addresses
+  default.grouplist = "127.0.0.1:8091"
+  #disable seata
+  disableGlobalTransaction = false
+}
\ No newline at end of file
diff --git a/compatible/src/test/resources/registry.conf 
b/compatible/src/test/resources/registry.conf
new file mode 100644
index 0000000000..5ad014bf55
--- /dev/null
+++ b/compatible/src/test/resources/registry.conf
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+registry {
+  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
+  type = "file"
+
+  file {
+    name = "file.conf"
+  }
+}
+
+config {
+  # file、nacos 、apollo、zk、consul、etcd3
+  type = "file"
+
+  file {
+    name = "file.conf"
+  }
+}
\ No newline at end of file
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 76429b7a50..03912b5345 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
@@ -16,6 +16,9 @@
  */
 package org.apache.seata.integration.tx.api.interceptor.handler;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Optional;
 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;
@@ -40,6 +43,11 @@ public abstract class AbstractProxyInvocationHandler 
implements ProxyInvocationH
         return doInvoke(invocation);
     }
 
+    public  <T extends Annotation> T getAnnotation(Method method, Class<?> 
targetClass, Class<T> annotationClass) {
+        return Optional.ofNullable(method).map(m -> 
m.getAnnotation(annotationClass))
+            .orElse(Optional.ofNullable(targetClass).map(t -> 
t.getAnnotation(annotationClass)).orElse(null));
+    }
+
     @Override
     public void setOrder(int order) {
         this.order = order;
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 ac942636df..e390b79433 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,10 +16,8 @@
  */
 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;
@@ -77,15 +75,15 @@ public class GlobalTransactionalInterceptorHandler extends 
AbstractProxyInvocati
     private static final Logger LOGGER = 
LoggerFactory.getLogger(GlobalTransactionalInterceptorHandler.class);
 
     private final TransactionalTemplate transactionalTemplate = new 
TransactionalTemplate();
-    protected final GlobalLockTemplate globalLockTemplate = new 
GlobalLockTemplate();
+    private final GlobalLockTemplate globalLockTemplate = new 
GlobalLockTemplate();
 
     private Set<String> methodsToProxy;
 
-    protected volatile boolean disable;
-    protected static final AtomicBoolean ATOMIC_DEGRADE_CHECK = new 
AtomicBoolean(false);
-    protected static volatile Integer degradeNum = 0;
+    private volatile boolean disable;
+    private static final AtomicBoolean ATOMIC_DEGRADE_CHECK = new 
AtomicBoolean(false);
+    private static volatile Integer degradeNum = 0;
     private static volatile Integer reachNum = 0;
-    protected static int degradeCheckAllowTimes;
+    private static int degradeCheckAllowTimes;
     protected AspectTransactional aspectTransactional;
     private static int degradeCheckPeriod;
 
@@ -145,22 +143,14 @@ public class GlobalTransactionalInterceptorHandler 
extends AbstractProxyInvocati
         Class<?> targetClass = invocation.getTarget().getClass();
         Method specificMethod = 
ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
         if (specificMethod != null && 
!specificMethod.getDeclaringClass().equals(Object.class)) {
-            final GlobalTransactional globalTransactionalAnnotation = 
getAnnotation(specificMethod, targetClass, GlobalTransactional.class);
-            final GlobalLock globalLockAnnotation = 
getAnnotation(specificMethod, targetClass, GlobalLock.class);
             boolean localDisable = disable || (ATOMIC_DEGRADE_CHECK.get() && 
degradeNum >= degradeCheckAllowTimes);
             if (!localDisable) {
+                final AspectTransactional globalTransactionalAnnotation = 
getAspectTransactional(specificMethod, targetClass);
+                final GlobalLockConfig globalLockAnnotation = 
getGlobalLockConfig(specificMethod, targetClass);
                 if (globalTransactionalAnnotation != null || 
this.aspectTransactional != null) {
                     AspectTransactional transactional;
                     if (globalTransactionalAnnotation != null) {
-                        transactional = new 
AspectTransactional(globalTransactionalAnnotation.timeoutMills(),
-                                globalTransactionalAnnotation.name(), 
globalTransactionalAnnotation.rollbackFor(),
-                                
globalTransactionalAnnotation.rollbackForClassName(),
-                                globalTransactionalAnnotation.noRollbackFor(),
-                                
globalTransactionalAnnotation.noRollbackForClassName(),
-                                globalTransactionalAnnotation.propagation(),
-                                
globalTransactionalAnnotation.lockRetryInterval(),
-                                globalTransactionalAnnotation.lockRetryTimes(),
-                                
globalTransactionalAnnotation.lockStrategyMode());
+                        transactional = globalTransactionalAnnotation;
                     } else {
                         transactional = this.aspectTransactional;
                     }
@@ -174,7 +164,7 @@ public class GlobalTransactionalInterceptorHandler extends 
AbstractProxyInvocati
     }
 
 
-    protected Object handleGlobalLock(final InvocationWrapper 
methodInvocation, final GlobalLock globalLockAnno) throws Throwable {
+    private Object handleGlobalLock(final InvocationWrapper methodInvocation, 
final GlobalLockConfig globalLockConfig) throws Throwable {
         return globalLockTemplate.execute(new GlobalLockExecutor() {
             @Override
             public Object execute() throws Throwable {
@@ -183,16 +173,13 @@ public class GlobalTransactionalInterceptorHandler 
extends AbstractProxyInvocati
 
             @Override
             public GlobalLockConfig getGlobalLockConfig() {
-                GlobalLockConfig config = new GlobalLockConfig();
-                
config.setLockRetryInterval(globalLockAnno.lockRetryInterval());
-                config.setLockRetryTimes(globalLockAnno.lockRetryTimes());
-                return config;
+                return globalLockConfig;
             }
         });
     }
 
-    protected Object handleGlobalTransaction(final InvocationWrapper 
methodInvocation,
-                                             final AspectTransactional 
aspectTransactional) throws Throwable {
+    Object handleGlobalTransaction(final InvocationWrapper methodInvocation,
+                                   final AspectTransactional 
aspectTransactional) throws Throwable {
         boolean succeed = true;
         try {
             return transactionalTemplate.execute(new TransactionalExecutor() {
@@ -287,10 +274,28 @@ public class GlobalTransactionalInterceptorHandler 
extends AbstractProxyInvocati
         }
     }
 
+    public GlobalLockConfig getGlobalLockConfig(Method method, Class<?> 
targetClass) {
+        final GlobalLock globalLockAnno = getAnnotation(method, targetClass, 
GlobalLock.class);
+        if (globalLockAnno != null) {
+            GlobalLockConfig config = new GlobalLockConfig();
+            config.setLockRetryInterval(globalLockAnno.lockRetryInterval());
+            config.setLockRetryTimes(globalLockAnno.lockRetryTimes());
+            return config;
+        } else {
+            return null;
+        }
+    }
 
-    public <T extends Annotation> T getAnnotation(Method method, Class<?> 
targetClass, Class<T> annotationClass) {
-        return Optional.ofNullable(method).map(m -> 
m.getAnnotation(annotationClass))
-                .orElse(Optional.ofNullable(targetClass).map(t -> 
t.getAnnotation(annotationClass)).orElse(null));
+    public AspectTransactional getAspectTransactional(Method method, Class<?> 
targetClass) {
+        final GlobalTransactional globalTransactionalAnnotation =
+            getAnnotation(method, targetClass, GlobalTransactional.class);
+        return globalTransactionalAnnotation != null ?
+            new 
AspectTransactional(globalTransactionalAnnotation.timeoutMills(), 
globalTransactionalAnnotation.name(),
+                globalTransactionalAnnotation.rollbackFor(), 
globalTransactionalAnnotation.rollbackForClassName(),
+                globalTransactionalAnnotation.noRollbackFor(), 
globalTransactionalAnnotation.noRollbackForClassName(),
+                globalTransactionalAnnotation.propagation(), 
globalTransactionalAnnotation.lockRetryInterval(),
+                globalTransactionalAnnotation.lockRetryTimes(), 
globalTransactionalAnnotation.lockStrategyMode()) :
+            null;
     }
 
     private String formatMethod(Method method) {
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 8192ff876b..7a4afb964c 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
@@ -49,7 +49,7 @@ public class GlobalTransactionalInterceptorParser implements 
InterfaceParser {
         Class<?>[] interfacesIfJdk = 
DefaultTargetClassParser.get().findInterfaces(target);
 
         if (existsAnnotation(serviceInterface) || 
existsAnnotation(interfacesIfJdk)) {
-            ProxyInvocationHandler proxyInvocationHandler = new 
GlobalTransactionalInterceptorHandler(FailureHandlerHolder.getFailureHandler(), 
methodsToProxy);
+            ProxyInvocationHandler proxyInvocationHandler = 
createProxyInvocationHandler();
             
ConfigurationCache.addConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
 (ConfigurationChangeListener) proxyInvocationHandler);
             return proxyInvocationHandler;
         }
@@ -57,6 +57,10 @@ public class GlobalTransactionalInterceptorParser implements 
InterfaceParser {
         return null;
     }
 
+    protected ProxyInvocationHandler createProxyInvocationHandler() {
+        return new 
GlobalTransactionalInterceptorHandler(FailureHandlerHolder.getFailureHandler(), 
methodsToProxy);
+    }
+
     @Override
     public IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass) {
         Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(beanClass);
diff --git 
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
 
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
index d0e843f045..063d2380be 100644
--- 
a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
+++ 
b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
@@ -25,5 +25,4 @@ public interface InterfaceParser {
 
     IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass);
 
-
 }
diff --git 
a/integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
 
b/integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
index a829b4df15..589ea02e36 100644
--- 
a/integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
+++ 
b/integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 
-class GlobalTransactionalInterceptorParserTest {
+public class GlobalTransactionalInterceptorParserTest {
 
     @Test
     void parserInterfaceToProxy() throws Exception {
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/TargetClassParser.java
 b/tm/src/main/java/org/apache/seata/tm/api/BaseTransaction.java
similarity index 82%
rename from 
compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/TargetClassParser.java
rename to tm/src/main/java/org/apache/seata/tm/api/BaseTransaction.java
index b8e377566e..2ca5586cf4 100644
--- 
a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/parser/TargetClassParser.java
+++ b/tm/src/main/java/org/apache/seata/tm/api/BaseTransaction.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.seata.integration.tx.api.interceptor.parser;
+package org.apache.seata.tm.api;
 
-public interface TargetClassParser extends 
org.apache.seata.integration.tx.api.interceptor.parser.TargetClassParser {
+public interface BaseTransaction {
 }
diff --git 
a/tm/src/main/java/org/apache/seata/tm/api/DefaultFailureHandlerImpl.java 
b/tm/src/main/java/org/apache/seata/tm/api/DefaultFailureHandlerImpl.java
index 2352341fc7..c008238182 100644
--- a/tm/src/main/java/org/apache/seata/tm/api/DefaultFailureHandlerImpl.java
+++ b/tm/src/main/java/org/apache/seata/tm/api/DefaultFailureHandlerImpl.java
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
  * The type Default failure handler.
  *
  */
-public class DefaultFailureHandlerImpl implements FailureHandler {
+public class DefaultFailureHandlerImpl implements TMFailureHandler {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultFailureHandlerImpl.class);
 
diff --git a/tm/src/main/java/org/apache/seata/tm/api/FailureHandler.java 
b/tm/src/main/java/org/apache/seata/tm/api/FailureHandler.java
index c0969aae0e..c7c0e83a91 100644
--- a/tm/src/main/java/org/apache/seata/tm/api/FailureHandler.java
+++ b/tm/src/main/java/org/apache/seata/tm/api/FailureHandler.java
@@ -20,7 +20,7 @@ package org.apache.seata.tm.api;
  * Callback on failure.
  *
  */
-public interface FailureHandler {
+public interface FailureHandler<T extends BaseTransaction> {
 
     /**
      * On begin failure.
@@ -28,7 +28,7 @@ public interface FailureHandler {
      * @param tx    the tx
      * @param cause the cause
      */
-    void onBeginFailure(GlobalTransaction tx, Throwable cause);
+    void onBeginFailure(T tx, Throwable cause);
 
     /**
      * On commit failure.
@@ -36,7 +36,7 @@ public interface FailureHandler {
      * @param tx    the tx
      * @param cause the cause
      */
-    void onCommitFailure(GlobalTransaction tx, Throwable cause);
+    void onCommitFailure(T tx, Throwable cause);
 
     /**
      * On rollback failure.
@@ -44,7 +44,7 @@ public interface FailureHandler {
      * @param tx                the tx
      * @param originalException the originalException
      */
-    void onRollbackFailure(GlobalTransaction tx, Throwable originalException);
+    void onRollbackFailure(T tx, Throwable originalException);
 
     /**
      * On rollback retrying
@@ -52,6 +52,6 @@ public interface FailureHandler {
      * @param tx                the tx
      * @param originalException the originalException
      */
-    void onRollbacking(GlobalTransaction tx, Throwable originalException);
+    void onRollbacking(T tx, Throwable originalException);
 
 }
diff --git a/tm/src/main/java/org/apache/seata/tm/api/FailureHandlerHolder.java 
b/tm/src/main/java/org/apache/seata/tm/api/FailureHandlerHolder.java
index b7251ad1d8..eb9daf5b0f 100644
--- a/tm/src/main/java/org/apache/seata/tm/api/FailureHandlerHolder.java
+++ b/tm/src/main/java/org/apache/seata/tm/api/FailureHandlerHolder.java
@@ -19,15 +19,15 @@ package org.apache.seata.tm.api;
 
 public class FailureHandlerHolder {
 
-    private static FailureHandler FAILURE_HANDLER_HOLDER = new 
DefaultFailureHandlerImpl();
+    private static FailureHandler<?> FAILURE_HANDLER_HOLDER = new 
DefaultFailureHandlerImpl();
 
-    public static void setFailureHandler(FailureHandler failureHandler) {
+    public static void setFailureHandler(FailureHandler<?> failureHandler) {
         if (failureHandler != null) {
             FAILURE_HANDLER_HOLDER = failureHandler;
         }
     }
 
-    public static FailureHandler getFailureHandler() {
+    public static FailureHandler<?> getFailureHandler() {
         return FAILURE_HANDLER_HOLDER;
     }
 
diff --git a/tm/src/main/java/org/apache/seata/tm/api/GlobalTransaction.java 
b/tm/src/main/java/org/apache/seata/tm/api/GlobalTransaction.java
index 130ac82ac4..69453e8034 100644
--- a/tm/src/main/java/org/apache/seata/tm/api/GlobalTransaction.java
+++ b/tm/src/main/java/org/apache/seata/tm/api/GlobalTransaction.java
@@ -24,7 +24,7 @@ import 
org.apache.seata.tm.api.transaction.SuspendedResourcesHolder;
  * Global transaction.
  *
  */
-public interface GlobalTransaction {
+public interface GlobalTransaction extends BaseTransaction {
 
     /**
      * Begin a new global transaction with default timeout and name.
diff --git 
a/compatible/src/main/java/io/seata/integration/tx/api/json/JsonParser.java 
b/tm/src/main/java/org/apache/seata/tm/api/TMFailureHandler.java
similarity index 84%
copy from 
compatible/src/main/java/io/seata/integration/tx/api/json/JsonParser.java
copy to tm/src/main/java/org/apache/seata/tm/api/TMFailureHandler.java
index e7ac74158d..34f75c9bf1 100644
--- a/compatible/src/main/java/io/seata/integration/tx/api/json/JsonParser.java
+++ b/tm/src/main/java/org/apache/seata/tm/api/TMFailureHandler.java
@@ -14,9 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.seata.integration.tx.api.json;
-
+package org.apache.seata.tm.api;
 
+/**
+ * Callback on failure.
+ *
+ */
+public interface TMFailureHandler extends FailureHandler<GlobalTransaction> {
 
-public interface JsonParser extends 
org.apache.seata.integration.tx.api.json.JsonParser {
 }


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

Reply via email to