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