From 985bc7c59570d379e9fd52d0c48c1925a9ab6e9f Mon Sep 17 00:00:00 2001 From: "changming.xie" <> Date: Tue, 3 Aug 2021 12:32:14 +0800 Subject: [PATCH 1/5] add dubbo filter --- .../AspectJTransactionMethodJoinPoint.java | 45 ++++++++++++++++ .../interceptor/CompensableMethodContext.java | 14 +++-- .../CompensableTransactionAspect.java | 3 +- .../CompensableTransactionInterceptor.java | 4 +- .../ResourceCoordinatorAspect.java | 4 ++ .../ResourceCoordinatorInterceptor.java | 10 ++-- .../TransactionMethodJoinPoint.java | 20 +++++++ .../filter/CompensableTransactionFilter.java | 46 ++++++++++++++++ .../DubboInvokeProceedingJoinPoint.java | 53 +++++++++++++++++++ .../dubbo/org.apache.dubbo.rpc.Filter | 1 + 10 files changed, 181 insertions(+), 19 deletions(-) create mode 100644 tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java create mode 100644 tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java create mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java create mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java create mode 100644 tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java new file mode 100644 index 00000000..7ab0f1e5 --- /dev/null +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java @@ -0,0 +1,45 @@ +package org.mengyun.tcctransaction.interceptor; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; + +import java.lang.reflect.Method; + +public class AspectJTransactionMethodJoinPoint implements TransactionMethodJoinPoint { + + ProceedingJoinPoint pjp; + + public AspectJTransactionMethodJoinPoint(ProceedingJoinPoint pjp) { + this.pjp = pjp; + } + + @Override + public Class getTargetClass() { + return pjp.getTarget().getClass(); + } + + @Override + public Method getMethod() { + return ((MethodSignature) pjp.getSignature()).getMethod(); + } + + @Override + public Object getTarget() { + return pjp.getTarget(); + } + + @Override + public Object[] getArgs() { + return pjp.getArgs(); + } + + @Override + public Object proceed() throws Throwable { + return pjp.proceed(); + } + + @Override + public Object proceed(Object[] args) throws Throwable { + return pjp.proceed(args); + } +} diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java index 16fa2e8a..7c75cef1 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java @@ -1,7 +1,5 @@ package org.mengyun.tcctransaction.interceptor; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.reflect.MethodSignature; import org.mengyun.tcctransaction.Transaction; import org.mengyun.tcctransaction.api.*; import org.mengyun.tcctransaction.common.ParticipantRole; @@ -15,7 +13,7 @@ */ public class CompensableMethodContext { - ProceedingJoinPoint pjp = null; + TransactionMethodJoinPoint pjp = null; Method method = null; Compensable compensable = null; @@ -28,14 +26,14 @@ public class CompensableMethodContext { private Transaction transaction = null; - public CompensableMethodContext(ProceedingJoinPoint pjp, Transaction transaction) { + public CompensableMethodContext(TransactionMethodJoinPoint pjp, Transaction transaction) { this.pjp = pjp; this.method = getCompensableMethod(); if (method == null) { - throw new RuntimeException(String.format("join point not found method, point is : %s", pjp.getSignature().getName())); + throw new RuntimeException(String.format("join point not found method, point is : %s", pjp.getMethod().getName())); } this.compensable = method.getAnnotation(Compensable.class); @@ -120,7 +118,7 @@ public ParticipantRole getParticipantRole() { //Method is @Compensable annotated, and has active transaction, and also has transaction context. //then the method need enlist the transaction as CONSUMER role, its role maybe PROVIDER before. - if(compensable != null && transaction != null && transactionContext != null) { + if (compensable != null && transaction != null && transactionContext != null) { return ParticipantRole.CONSUMER; } @@ -137,7 +135,7 @@ public ParticipantRole getParticipantRole() { private Method getCompensableMethod() { - Method method = ((MethodSignature) (pjp.getSignature())).getMethod(); + Method method = pjp.getMethod(); Method foundMethod = null; @@ -148,7 +146,7 @@ private Method getCompensableMethod() { Method targetMethod = null; try { - targetMethod = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes()); + targetMethod = pjp.getTargetClass().getMethod(method.getName(), method.getParameterTypes()); } catch (NoSuchMethodException e) { targetMethod = null; } diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java index fa39f8ed..a4f95f78 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java @@ -24,8 +24,7 @@ public void compensableService() { @Around("compensableService()") public Object interceptCompensableMethod(ProceedingJoinPoint pjp) throws Throwable { - - return compensableTransactionInterceptor.interceptCompensableMethod(pjp); + return compensableTransactionInterceptor.interceptCompensableMethod(new AspectJTransactionMethodJoinPoint(pjp)); } public abstract int getOrder(); diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java index db2d8d9c..f4c0a964 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java @@ -27,7 +27,7 @@ public void setTransactionManager(TransactionManager transactionManager) { this.transactionManager = transactionManager; } - public Object interceptCompensableMethod(ProceedingJoinPoint pjp) throws Throwable { + public Object interceptCompensableMethod(TransactionMethodJoinPoint pjp) throws Throwable { Transaction transaction = transactionManager.getCurrentTransaction(); CompensableMethodContext compensableMethodContext = new CompensableMethodContext(pjp, transaction); @@ -44,7 +44,6 @@ public Object interceptCompensableMethod(ProceedingJoinPoint pjp) throws Throwab } } - private Object rootMethodProceed(CompensableMethodContext compensableMethodContext) throws Throwable { Object returnValue = null; @@ -81,7 +80,6 @@ private Object providerMethodProceed(CompensableMethodContext compensableMethodC Transaction transaction = null; - boolean asyncConfirm = compensableMethodContext.getAnnotation().asyncConfirm(); boolean asyncCancel = compensableMethodContext.getAnnotation().asyncCancel(); diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java index d5e4cb3a..add06eed 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java @@ -20,6 +20,10 @@ public void transactionContextCall() { @Around("transactionContextCall()") public Object interceptTransactionContextMethod(ProceedingJoinPoint pjp) throws Throwable { + return interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp)); + } + + public Object interceptTransactionContextMethod(TransactionMethodJoinPoint pjp) throws Throwable { return resourceCoordinatorInterceptor.interceptTransactionContextMethod(pjp); } diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java index ea0cdf7d..5a4702d8 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java @@ -1,7 +1,5 @@ package org.mengyun.tcctransaction.interceptor; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.reflect.MethodSignature; import org.mengyun.tcctransaction.InvocationContext; import org.mengyun.tcctransaction.Participant; import org.mengyun.tcctransaction.Transaction; @@ -23,7 +21,7 @@ public void setTransactionManager(TransactionManager transactionManager) { this.transactionManager = transactionManager; } - public Object interceptTransactionContextMethod(ProceedingJoinPoint pjp) throws Throwable { + public Object interceptTransactionContextMethod(TransactionMethodJoinPoint pjp) throws Throwable { Transaction transaction = transactionManager.getCurrentTransaction(); @@ -55,7 +53,7 @@ public Object interceptTransactionContextMethod(ProceedingJoinPoint pjp) throws return pjp.proceed(pjp.getArgs()); } - private Participant enlistParticipant(ProceedingJoinPoint pjp) { + private Participant enlistParticipant(TransactionMethodJoinPoint pjp) { Transaction transaction = transactionManager.getCurrentTransaction(); CompensableMethodContext compensableMethodContext = new CompensableMethodContext(pjp, transaction); @@ -71,10 +69,10 @@ private Participant enlistParticipant(ProceedingJoinPoint pjp) { TransactionXid xid = new TransactionXid(transaction.getXid().getGlobalTransactionId()); if (compensableMethodContext.getTransactionContext() == null) { - FactoryBuilder.factoryOf(transactionContextEditorClass).getInstance().set(new TransactionContext(transaction.getRootXid(), xid, TransactionStatus.TRYING.getId(), ParticipantStatus.TRYING.getId()), pjp.getTarget(), ((MethodSignature) pjp.getSignature()).getMethod(), pjp.getArgs()); + FactoryBuilder.factoryOf(transactionContextEditorClass).getInstance().set(new TransactionContext(transaction.getRootXid(), xid, TransactionStatus.TRYING.getId(), ParticipantStatus.TRYING.getId()), pjp.getTarget(), pjp.getMethod(), pjp.getArgs()); } - Class targetClass = ReflectionUtils.getDeclaringType(pjp.getTarget().getClass(), compensableMethodContext.getMethod().getName(), compensableMethodContext.getMethod().getParameterTypes()); + Class targetClass = ReflectionUtils.getDeclaringType(pjp.getTargetClass(), compensableMethodContext.getMethod().getName(), compensableMethodContext.getMethod().getParameterTypes()); InvocationContext confirmInvocation = new InvocationContext(targetClass, diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java new file mode 100644 index 00000000..710c70d1 --- /dev/null +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java @@ -0,0 +1,20 @@ +package org.mengyun.tcctransaction.interceptor; + +import java.lang.reflect.Method; + +public interface TransactionMethodJoinPoint { + + Class getTargetClass(); + + Method getMethod(); + + Object getTarget(); + + Object[] getArgs(); + + Object proceed() throws Throwable; + + Object proceed(Object[] var1) throws Throwable; + + +} diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java new file mode 100644 index 00000000..7a7daec6 --- /dev/null +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java @@ -0,0 +1,46 @@ +package org.mengyun.tcctransaction.dubbo.filter; + +import com.alibaba.dubbo.common.Constants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.*; +import org.mengyun.tcctransaction.SystemException; +import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.interceptor.ResourceCoordinatorAspect; +import org.mengyun.tcctransaction.support.FactoryBuilder; + +import java.lang.reflect.Method; + +@Activate(group = {Constants.CONSUMER}) +public class CompensableTransactionFilter implements Filter { + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + + return invoker.invoke(invocation); + } + + private Result doInvoke(Invoker invoker, Invocation invocation) { + + Method method = null; + + try { + + method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()); + + Compensable compensable = method.getAnnotation(Compensable.class); + + if (compensable != null) { + + DubboInvokeProceedingJoinPoint pjp = new DubboInvokeProceedingJoinPoint(invocation); + + return (Result) FactoryBuilder.factoryOf(ResourceCoordinatorAspect.class).getInstance().interceptTransactionContextMethod(pjp); + + } else { + return invoker.invoke(invocation); + } + + } catch (Throwable e) { + throw new SystemException(e); + } + } +} diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java new file mode 100644 index 00000000..b1d64a92 --- /dev/null +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java @@ -0,0 +1,53 @@ +package org.mengyun.tcctransaction.dubbo.filter; + +import org.apache.dubbo.rpc.Constants; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.model.ConsumerMethodModel; +import org.apache.dubbo.rpc.model.ConsumerModel; +import org.mengyun.tcctransaction.interceptor.TransactionMethodJoinPoint; + +import java.lang.reflect.Method; + +public class DubboInvokeProceedingJoinPoint implements TransactionMethodJoinPoint { + + private Invocation invocation; + + public DubboInvokeProceedingJoinPoint(Invocation invocation) { + this.invocation = invocation; + } + + @Override + public Class getTargetClass() { + return invocation.getInvoker().getInterface(); + } + + @Override + public Method getMethod() { +// try { +// return getTargetClass().getMethod(invocation.getMethodName(), invocation.getParameterTypes()); +// } catch (NoSuchMethodException e) { +// throw new SystemException(e); +// } + return ((ConsumerMethodModel) invocation.getAttributes().get(Constants.METHOD_MODEL)).getMethod(); + } + + @Override + public Object getTarget() { + return ((ConsumerModel) invocation.getAttributes().get(Constants.CONSUMER_MODEL)).getProxyObject(); + } + + @Override + public Object[] getArgs() { + return invocation.getArguments(); + } + + @Override + public Object proceed() throws Throwable { + return invocation.getInvoker().invoke(invocation); + } + + @Override + public Object proceed(Object[] args) throws Throwable { + return proceed(); + } +} diff --git a/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter b/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter new file mode 100644 index 00000000..98e5282d --- /dev/null +++ b/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter @@ -0,0 +1 @@ +compensableTransaction=org.mengyun.tcctransaction.dubbo.filter.CompensableTransactionFilter \ No newline at end of file From fb004c81a070d0dfa6147dca8200a1a3fe25538c Mon Sep 17 00:00:00 2001 From: "changming.xie" <> Date: Wed, 4 Aug 2021 18:47:29 +0800 Subject: [PATCH 2/5] add CompensableTransactionFilter, remove TccJavassist. --- .../tcctransaction/api/Compensable.java | 66 +----- .../mengyun/tcctransaction/api/EnableTcc.java | 5 + .../api/NullableTransactionContextEditor.java | 16 ++ .../ParameterTransactionContextEditor.java | 53 +++++ .../AspectJTransactionMethodJoinPoint.java | 17 +- .../interceptor/CompensableMethodContext.java | 81 ++------ .../CompensableTransactionAspect.java | 10 +- .../CompensableTransactionInterceptor.java | 2 +- .../ResourceCoordinatorAspect.java | 17 +- .../ResourceCoordinatorInterceptor.java | 2 +- .../TransactionMethodJoinPoint.java | 9 +- .../utils/TransactionUtils.java | 20 -- .../filter/CompensableTransactionFilter.java | 19 +- .../DubboInvokeProceedingJoinPoint.java | 17 +- .../jdk/TccInvokerInvocationHandler.java | 5 +- ...ry => ##org.apache.dubbo.rpc.ProxyFactory} | 0 .../main/resources/tcc-transaction-dubbo.xml | 2 +- .../capital/api/CapitalTradeOrderService.java | 4 +- .../service/CapitalTradeOrderServiceImpl.java | 2 +- .../src/main/webapp/WEB-INF/web.xml | 2 +- .../api/RedPacketTradeOrderService.java | 4 +- .../RedPacketTradeOrderServiceImpl.java | 2 +- .../spring/local/appcontext-service-tcc.xml | 196 ++++++++---------- .../spring/local/appcontext-service-tcc.xml | 196 ++++++++---------- .../spring/local/appcontext-service-tcc.xml | 194 ++++++++--------- .../src/main/resources/h2.sql | 4 +- .../src/main/resources/h2.sql | 4 +- 27 files changed, 445 insertions(+), 504 deletions(-) create mode 100644 tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java create mode 100644 tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/NullableTransactionContextEditor.java create mode 100644 tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java delete mode 100644 tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/utils/TransactionUtils.java rename tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/{org.apache.dubbo.rpc.ProxyFactory => ##org.apache.dubbo.rpc.ProxyFactory} (100%) diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java index 1b1af423..a5db0a66 100644 --- a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java @@ -4,7 +4,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.Method; /** * Created by changmingxie on 10/25/15. @@ -19,72 +18,9 @@ public String cancelMethod() default ""; - public Class transactionContextEditor() default DefaultTransactionContextEditor.class; - public boolean asyncConfirm() default false; public boolean asyncCancel() default false; - class NullableTransactionContextEditor implements TransactionContextEditor { - - @Override - public TransactionContext get(Object target, Method method, Object[] args) { - return null; - } - - @Override - public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) { - - } - } - - class DefaultTransactionContextEditor implements TransactionContextEditor { - - public static int getTransactionContextParamPosition(Class[] parameterTypes) { - - int position = -1; - - for (int i = 0; i < parameterTypes.length; i++) { - if (parameterTypes[i].equals(org.mengyun.tcctransaction.api.TransactionContext.class)) { - position = i; - break; - } - } - return position; - } - - public static TransactionContext getTransactionContextFromArgs(Object[] args) { - - TransactionContext transactionContext = null; - - for (Object arg : args) { - if (arg != null && org.mengyun.tcctransaction.api.TransactionContext.class.isAssignableFrom(arg.getClass())) { - - transactionContext = (org.mengyun.tcctransaction.api.TransactionContext) arg; - } - } - - return transactionContext; - } - - @Override - public TransactionContext get(Object target, Method method, Object[] args) { - int position = getTransactionContextParamPosition(method.getParameterTypes()); - - if (position >= 0) { - return (TransactionContext) args[position]; - } - - return null; - } - - @Override - public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) { - - int position = getTransactionContextParamPosition(method.getParameterTypes()); - if (position >= 0) { - args[position] = transactionContext; - } - } - } + public Class transactionContextEditor() default ParameterTransactionContextEditor.class; } \ No newline at end of file diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java new file mode 100644 index 00000000..05463292 --- /dev/null +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java @@ -0,0 +1,5 @@ +package org.mengyun.tcctransaction.api; + +public @interface EnableTcc { + public Class transactionContextEditor() default NullableTransactionContextEditor.class; +} diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/NullableTransactionContextEditor.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/NullableTransactionContextEditor.java new file mode 100644 index 00000000..f7e44486 --- /dev/null +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/NullableTransactionContextEditor.java @@ -0,0 +1,16 @@ +package org.mengyun.tcctransaction.api; + +import java.lang.reflect.Method; + +public class NullableTransactionContextEditor implements TransactionContextEditor { + + @Override + public TransactionContext get(Object target, Method method, Object[] args) { + return null; + } + + @Override + public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) { + + } +} \ No newline at end of file diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java new file mode 100644 index 00000000..95ca2852 --- /dev/null +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java @@ -0,0 +1,53 @@ +package org.mengyun.tcctransaction.api; + +import java.lang.reflect.Method; + +public class ParameterTransactionContextEditor implements TransactionContextEditor { + + public static int getTransactionContextParamPosition(Class[] parameterTypes) { + + int position = -1; + + for (int i = 0; i < parameterTypes.length; i++) { + if (parameterTypes[i].equals(org.mengyun.tcctransaction.api.TransactionContext.class)) { + position = i; + break; + } + } + return position; + } + + public static TransactionContext getTransactionContextFromArgs(Object[] args) { + + TransactionContext transactionContext = null; + + for (Object arg : args) { + if (arg != null && org.mengyun.tcctransaction.api.TransactionContext.class.isAssignableFrom(arg.getClass())) { + + transactionContext = (org.mengyun.tcctransaction.api.TransactionContext) arg; + } + } + + return transactionContext; + } + + @Override + public TransactionContext get(Object target, Method method, Object[] args) { + int position = getTransactionContextParamPosition(method.getParameterTypes()); + + if (position >= 0) { + return (TransactionContext) args[position]; + } + + return null; + } + + @Override + public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) { + + int position = getTransactionContextParamPosition(method.getParameterTypes()); + if (position >= 0) { + args[position] = transactionContext; + } + } +} diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java index 7ab0f1e5..4c2e3b0c 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/AspectJTransactionMethodJoinPoint.java @@ -2,20 +2,31 @@ import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; +import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.TransactionContextEditor; import java.lang.reflect.Method; public class AspectJTransactionMethodJoinPoint implements TransactionMethodJoinPoint { ProceedingJoinPoint pjp; + Compensable compensable; + Class transactionContextEditorClass; - public AspectJTransactionMethodJoinPoint(ProceedingJoinPoint pjp) { + public AspectJTransactionMethodJoinPoint(ProceedingJoinPoint pjp, Compensable compensable, Class transactionContextEditorClass) { this.pjp = pjp; + this.compensable = compensable; + this.transactionContextEditorClass = transactionContextEditorClass; } @Override - public Class getTargetClass() { - return pjp.getTarget().getClass(); + public Compensable getCompensable() { + return compensable; + } + + @Override + public Class getTransactionContextEditorClass() { + return transactionContextEditorClass; } @Override diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java index 7c75cef1..35e250ab 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableMethodContext.java @@ -1,7 +1,10 @@ package org.mengyun.tcctransaction.interceptor; import org.mengyun.tcctransaction.Transaction; -import org.mengyun.tcctransaction.api.*; +import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.TransactionContext; +import org.mengyun.tcctransaction.api.TransactionContextEditor; +import org.mengyun.tcctransaction.api.UniqueIdentity; import org.mengyun.tcctransaction.common.ParticipantRole; import org.mengyun.tcctransaction.support.FactoryBuilder; @@ -14,60 +17,33 @@ public class CompensableMethodContext { TransactionMethodJoinPoint pjp = null; - Method method = null; - Compensable compensable = null; - Propagation propagation = null; + private Transaction transaction = null; TransactionContext transactionContext = null; - Class transactionContextEditorClass; - String confirmMethodName = null; - String cancelMethodName = null; - private Transaction transaction = null; + Compensable compensable = null; public CompensableMethodContext(TransactionMethodJoinPoint pjp, Transaction transaction) { - this.pjp = pjp; - this.method = getCompensableMethod(); - - if (method == null) { - throw new RuntimeException(String.format("join point not found method, point is : %s", pjp.getMethod().getName())); - } - - this.compensable = method.getAnnotation(Compensable.class); - - if (this.compensable != null) { - this.propagation = compensable.propagation(); - transactionContextEditorClass = compensable.transactionContextEditor(); - confirmMethodName = this.compensable.confirmMethod(); - cancelMethodName = this.compensable.cancelMethod(); - } else { - transactionContextEditorClass = Compensable.DefaultTransactionContextEditor.class; - confirmMethodName = this.method.getName(); - cancelMethodName = this.method.getName(); - } + this.transaction = transaction; - this.transactionContext = FactoryBuilder.factoryOf(transactionContextEditorClass).getInstance().get(pjp.getTarget(), method, pjp.getArgs()); + this.compensable = pjp.getCompensable(); - this.transaction = transaction; + this.transactionContext = FactoryBuilder.factoryOf(pjp.getTransactionContextEditorClass()).getInstance().get(pjp.getTarget(), pjp.getMethod(), pjp.getArgs()); } public Compensable getAnnotation() { return compensable; } - public Propagation getPropagation() { - return propagation; - } - public TransactionContext getTransactionContext() { return transactionContext; } public Method getMethod() { - return method; + return pjp.getMethod(); } public Object getUniqueIdentity() { @@ -133,50 +109,19 @@ public ParticipantRole getParticipantRole() { } - private Method getCompensableMethod() { - - Method method = pjp.getMethod(); - - Method foundMethod = null; - - //first find if exist @Compensable - if (method.getAnnotation(Compensable.class) != null) { - foundMethod = method; - } else { - - Method targetMethod = null; - try { - targetMethod = pjp.getTargetClass().getMethod(method.getName(), method.getParameterTypes()); - } catch (NoSuchMethodException e) { - targetMethod = null; - } - - if (targetMethod != null && targetMethod.getAnnotation(Compensable.class) != null) { - foundMethod = targetMethod; - } else { - - if (Compensable.DefaultTransactionContextEditor.getTransactionContextParamPosition(method.getParameterTypes()) >= 0) { - foundMethod = method; - } - } - } - - return foundMethod; - } - public Object proceed() throws Throwable { return this.pjp.proceed(); } public Class getTransactionContextEditorClass() { - return transactionContextEditorClass; + return pjp.getTransactionContextEditorClass(); } public String getConfirmMethodName() { - return confirmMethodName; + return compensable == null ? pjp.getMethod().getName() : compensable.confirmMethod(); } public String getCancelMethodName() { - return cancelMethodName; + return compensable == null ? pjp.getMethod().getName() : compensable.cancelMethod(); } } \ No newline at end of file diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java index a4f95f78..e7b79ea0 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java @@ -4,6 +4,8 @@ import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.mengyun.tcctransaction.api.Compensable; /** * Created by changmingxie on 10/30/15. @@ -18,13 +20,15 @@ public void setCompensableTransactionInterceptor(CompensableTransactionIntercept } @Pointcut("@annotation(org.mengyun.tcctransaction.api.Compensable)") - public void compensableService() { + public void compensableTransactionPointcut() { } - @Around("compensableService()") + @Around("compensableTransactionPointcut()") public Object interceptCompensableMethod(ProceedingJoinPoint pjp) throws Throwable { - return compensableTransactionInterceptor.interceptCompensableMethod(new AspectJTransactionMethodJoinPoint(pjp)); + + Compensable compensable = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Compensable.class); + return compensableTransactionInterceptor.interceptCompensableMethod(new AspectJTransactionMethodJoinPoint(pjp, compensable, compensable.transactionContextEditor())); } public abstract int getOrder(); diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java index f4c0a964..f6ef1504 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java @@ -40,7 +40,7 @@ public Object interceptCompensableMethod(TransactionMethodJoinPoint pjp) throws case PROVIDER: return providerMethodProceed(compensableMethodContext); default: - return pjp.proceed(); + return compensableMethodContext.proceed(); } } diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java index add06eed..458e0f33 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java @@ -4,6 +4,9 @@ import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.ParameterTransactionContextEditor; /** * Created by changmingxie on 11/8/15. @@ -14,13 +17,19 @@ public abstract class ResourceCoordinatorAspect { private ResourceCoordinatorInterceptor resourceCoordinatorInterceptor; @Pointcut("@annotation(org.mengyun.tcctransaction.api.Compensable) || execution(* *(org.mengyun.tcctransaction.api.TransactionContext,..))") - public void transactionContextCall() { + public void transactionResourcePointcut() { } - @Around("transactionContextCall()") - public Object interceptTransactionContextMethod(ProceedingJoinPoint pjp) throws Throwable { - return interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp)); + + @Around("transactionResourcePointcut()") + public Object interceptTransactionResourceMethodWithCompensableAnnotation(ProceedingJoinPoint pjp) throws Throwable { + Compensable compensable = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Compensable.class); + if (compensable != null) { + return interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp, compensable, compensable.transactionContextEditor())); + } else { + return interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp, null, ParameterTransactionContextEditor.class)); + } } public Object interceptTransactionContextMethod(TransactionMethodJoinPoint pjp) throws Throwable { diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java index 5a4702d8..c4aa64f1 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java @@ -72,7 +72,7 @@ private Participant enlistParticipant(TransactionMethodJoinPoint pjp) { FactoryBuilder.factoryOf(transactionContextEditorClass).getInstance().set(new TransactionContext(transaction.getRootXid(), xid, TransactionStatus.TRYING.getId(), ParticipantStatus.TRYING.getId()), pjp.getTarget(), pjp.getMethod(), pjp.getArgs()); } - Class targetClass = ReflectionUtils.getDeclaringType(pjp.getTargetClass(), compensableMethodContext.getMethod().getName(), compensableMethodContext.getMethod().getParameterTypes()); + Class targetClass = ReflectionUtils.getDeclaringType(pjp.getTarget().getClass(), compensableMethodContext.getMethod().getName(), compensableMethodContext.getMethod().getParameterTypes()); InvocationContext confirmInvocation = new InvocationContext(targetClass, diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java index 710c70d1..d29534e9 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/TransactionMethodJoinPoint.java @@ -1,10 +1,15 @@ package org.mengyun.tcctransaction.interceptor; +import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.TransactionContextEditor; + import java.lang.reflect.Method; public interface TransactionMethodJoinPoint { - Class getTargetClass(); + Compensable getCompensable(); + + Class getTransactionContextEditorClass(); Method getMethod(); @@ -14,7 +19,7 @@ public interface TransactionMethodJoinPoint { Object proceed() throws Throwable; - Object proceed(Object[] var1) throws Throwable; + Object proceed(Object[] args) throws Throwable; } diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/utils/TransactionUtils.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/utils/TransactionUtils.java deleted file mode 100644 index e56ddbba..00000000 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/utils/TransactionUtils.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.mengyun.tcctransaction.utils; - -import org.mengyun.tcctransaction.api.Propagation; -import org.mengyun.tcctransaction.interceptor.CompensableMethodContext; - -/** - * Created by changming.xie on 2/23/17. - */ -public class TransactionUtils { - - public static boolean isLegalTransactionContext(boolean isTransactionActive, CompensableMethodContext compensableMethodContext) { - - - if (compensableMethodContext.getPropagation().equals(Propagation.MANDATORY) && !isTransactionActive && compensableMethodContext.getTransactionContext() == null) { - return false; - } - - return true; - } -} diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java index 7a7daec6..a75d711c 100644 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java @@ -4,7 +4,9 @@ import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.rpc.*; import org.mengyun.tcctransaction.SystemException; -import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.EnableTcc; +import org.mengyun.tcctransaction.api.ParameterTransactionContextEditor; +import org.mengyun.tcctransaction.dubbo.context.DubboTransactionContextEditor; import org.mengyun.tcctransaction.interceptor.ResourceCoordinatorAspect; import org.mengyun.tcctransaction.support.FactoryBuilder; @@ -16,7 +18,8 @@ public class CompensableTransactionFilter implements Filter { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - return invoker.invoke(invocation); +// return invoker.invoke(invocation); + return doInvoke(invoker, invocation); } private Result doInvoke(Invoker invoker, Invocation invocation) { @@ -27,14 +30,18 @@ private Result doInvoke(Invoker invoker, Invocation invocation) { method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()); - Compensable compensable = method.getAnnotation(Compensable.class); + boolean hasTransactionContextParameter = ParameterTransactionContextEditor.getTransactionContextParamPosition(invocation.getParameterTypes()) > 0; - if (compensable != null) { + if (hasTransactionContextParameter) { + // in this case, will handler by ResourceCoordinatorAspect + return invoker.invoke(invocation); + } - DubboInvokeProceedingJoinPoint pjp = new DubboInvokeProceedingJoinPoint(invocation); + EnableTcc enableTcc = method.getAnnotation(EnableTcc.class); + if (enableTcc != null) { + DubboInvokeProceedingJoinPoint pjp = new DubboInvokeProceedingJoinPoint(invocation, null, DubboTransactionContextEditor.class); return (Result) FactoryBuilder.factoryOf(ResourceCoordinatorAspect.class).getInstance().interceptTransactionContextMethod(pjp); - } else { return invoker.invoke(invocation); } diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java index b1d64a92..ed8cdff1 100644 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java @@ -4,6 +4,8 @@ import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.model.ConsumerMethodModel; import org.apache.dubbo.rpc.model.ConsumerModel; +import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.TransactionContextEditor; import org.mengyun.tcctransaction.interceptor.TransactionMethodJoinPoint; import java.lang.reflect.Method; @@ -11,14 +13,23 @@ public class DubboInvokeProceedingJoinPoint implements TransactionMethodJoinPoint { private Invocation invocation; + Compensable compensable; + Class transactionContextEditorClass; - public DubboInvokeProceedingJoinPoint(Invocation invocation) { + public DubboInvokeProceedingJoinPoint(Invocation invocation, Compensable compensable, Class transactionContextEditorClass) { this.invocation = invocation; + this.compensable = compensable; + this.transactionContextEditorClass = transactionContextEditorClass; } @Override - public Class getTargetClass() { - return invocation.getInvoker().getInterface(); + public Compensable getCompensable() { + return compensable; + } + + @Override + public Class getTransactionContextEditorClass() { + return transactionContextEditorClass; } @Override diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java index 66c3a266..0712df5c 100644 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java @@ -7,6 +7,7 @@ import org.mengyun.tcctransaction.api.Compensable; import org.mengyun.tcctransaction.api.Propagation; import org.mengyun.tcctransaction.dubbo.context.DubboTransactionContextEditor; +import org.mengyun.tcctransaction.interceptor.AspectJTransactionMethodJoinPoint; import org.mengyun.tcctransaction.interceptor.ResourceCoordinatorAspect; import org.mengyun.tcctransaction.support.FactoryBuilder; import org.mengyun.tcctransaction.utils.ReflectionUtils; @@ -38,12 +39,12 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl if (StringUtils.isEmpty(compensable.confirmMethod())) { ReflectionUtils.changeAnnotationValue(compensable, "confirmMethod", method.getName()); ReflectionUtils.changeAnnotationValue(compensable, "cancelMethod", method.getName()); - ReflectionUtils.changeAnnotationValue(compensable, "transactionContextEditor", DubboTransactionContextEditor.class); +// ReflectionUtils.changeAnnotationValue(compensable, "transactionContextEditor", DubboTransactionContextEditor.class); ReflectionUtils.changeAnnotationValue(compensable, "propagation", Propagation.SUPPORTS); } ProceedingJoinPoint pjp = new MethodProceedingJoinPoint(proxy, target, method, args); - return FactoryBuilder.factoryOf(ResourceCoordinatorAspect.class).getInstance().interceptTransactionContextMethod(pjp); + return FactoryBuilder.factoryOf(ResourceCoordinatorAspect.class).getInstance().interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp,compensable,DubboTransactionContextEditor.class)); } else { return super.invoke(target, method, args); } diff --git a/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory b/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/##org.apache.dubbo.rpc.ProxyFactory similarity index 100% rename from tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory rename to tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/##org.apache.dubbo.rpc.ProxyFactory diff --git a/tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml b/tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml index 57fd02dd..35c94575 100644 --- a/tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml +++ b/tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml @@ -4,5 +4,5 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> - + \ No newline at end of file diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/api/CapitalTradeOrderService.java b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/api/CapitalTradeOrderService.java index 0480e27e..1cf1f51a 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/api/CapitalTradeOrderService.java +++ b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/api/CapitalTradeOrderService.java @@ -1,6 +1,6 @@ package org.mengyun.tcctransaction.sample.dubbo.capital.api; -import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.EnableTcc; import org.mengyun.tcctransaction.sample.dubbo.capital.api.dto.CapitalTradeOrderDto; /** @@ -8,7 +8,7 @@ */ public interface CapitalTradeOrderService { - @Compensable + @EnableTcc public String record(CapitalTradeOrderDto tradeOrderDto); } diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java index 5872dc48..912c7165 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java +++ b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java @@ -29,7 +29,7 @@ public class CapitalTradeOrderServiceImpl implements CapitalTradeOrderService { TradeOrderRepository tradeOrderRepository; @Override - @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord", transactionContextEditor = DubboTransactionContextEditor.class) + @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord") @Transactional public String record(CapitalTradeOrderDto tradeOrderDto) { diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-order/src/main/webapp/WEB-INF/web.xml b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-order/src/main/webapp/WEB-INF/web.xml index e26254a3..913eff38 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-order/src/main/webapp/WEB-INF/web.xml +++ b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-order/src/main/webapp/WEB-INF/web.xml @@ -13,7 +13,7 @@ contextConfigLocation - classpath:tcc-transaction-dubbo.xml,classpath*:config/spring/local/appcontext-*.xml + classpath*:config/spring/local/appcontext-*.xml diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/api/RedPacketTradeOrderService.java b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/api/RedPacketTradeOrderService.java index 89caf877..d7323789 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/api/RedPacketTradeOrderService.java +++ b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket-api/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/api/RedPacketTradeOrderService.java @@ -1,6 +1,6 @@ package org.mengyun.tcctransaction.sample.dubbo.redpacket.api; -import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.EnableTcc; import org.mengyun.tcctransaction.sample.dubbo.redpacket.api.dto.RedPacketTradeOrderDto; /** @@ -8,6 +8,6 @@ */ public interface RedPacketTradeOrderService { - @Compensable + @EnableTcc public String record(RedPacketTradeOrderDto tradeOrderDto); } diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java index bde93d18..b38b3692 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java +++ b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java @@ -29,7 +29,7 @@ public class RedPacketTradeOrderServiceImpl implements RedPacketTradeOrderServic TradeOrderRepository tradeOrderRepository; @Override - @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord", transactionContextEditor = DubboTransactionContextEditor.class) + @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord") @Transactional public String record(RedPacketTradeOrderDto tradeOrderDto) { diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml index b8138723..7b2bb6a8 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml +++ b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml @@ -4,8 +4,6 @@ xmlns="http://www.springframework.org/schema/beans" xmlns:tcc="http://www.tcctransaction.org/schema/tcc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.tcctransaction.org/schema/tcc http://www.tcctransaction.org/schema/tcc.xsd"> - - @@ -16,109 +14,97 @@ - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml index 81050933..59959696 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml +++ b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml @@ -4,9 +4,6 @@ xmlns="http://www.springframework.org/schema/beans" xmlns:tcc="http://www.tcctransaction.org/schema/tcc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.tcctransaction.org/schema/tcc http://www.tcctransaction.org/schema/tcc.xsd"> - - - @@ -16,109 +13,98 @@ - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml index d5ca0b77..307c5c39 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml +++ b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml @@ -4,8 +4,6 @@ xmlns="http://www.springframework.org/schema/beans" xmlns:tcc="http://www.tcctransaction.org/schema/tcc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.tcctransaction.org/schema/tcc http://www.tcctransaction.org/schema/tcc.xsd"> - - @@ -16,109 +14,97 @@ - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-captial/src/main/resources/h2.sql b/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-captial/src/main/resources/h2.sql index d20a051c..b3e47b8c 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-captial/src/main/resources/h2.sql +++ b/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-captial/src/main/resources/h2.sql @@ -17,6 +17,6 @@ CREATE TABLE `CAP_TRADE_ORDER` ( UNIQUE KEY `UX_MERCHANT_ORDER_NO` (`MERCHANT_ORDER_NO`) ) ; -INSERT INTO `CAP_CAPITAL_ACCOUNT` (`CAPITAL_ACCOUNT_ID`, `BALANCE_AMOUNT`, `USER_ID`) VALUES (1,10000,1000); +INSERT INTO `CAP_CAPITAL_ACCOUNT` (`CAPITAL_ACCOUNT_ID`, `BALANCE_AMOUNT`, `USER_ID`) VALUES (1,100000,1000); -INSERT INTO `CAP_CAPITAL_ACCOUNT` (`CAPITAL_ACCOUNT_ID`, `BALANCE_AMOUNT`, `USER_ID`) VALUES (2,10000,2000); \ No newline at end of file +INSERT INTO `CAP_CAPITAL_ACCOUNT` (`CAPITAL_ACCOUNT_ID`, `BALANCE_AMOUNT`, `USER_ID`) VALUES (2,100000,2000); \ No newline at end of file diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-redpacket/src/main/resources/h2.sql b/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-redpacket/src/main/resources/h2.sql index 37bcf5cf..201c8b3a 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-redpacket/src/main/resources/h2.sql +++ b/tcc-transaction-tutorial-sample/tcc-transaction-sample-domain/tcc-transaction-sample-redpacket/src/main/resources/h2.sql @@ -17,5 +17,5 @@ CREATE TABLE `RED_TRADE_ORDER` ( UNIQUE KEY `MERCHANT_ORDER_NO_UNIQUE` (`MERCHANT_ORDER_NO`) ); -INSERT INTO `RED_RED_PACKET_ACCOUNT` (`RED_PACKET_ACCOUNT_ID`,`BALANCE_AMOUNT`,`USER_ID`) VALUES (1,950,1000); -INSERT INTO `RED_RED_PACKET_ACCOUNT` (`RED_PACKET_ACCOUNT_ID`,`BALANCE_AMOUNT`,`USER_ID`) VALUES (2,500,2000); +INSERT INTO `RED_RED_PACKET_ACCOUNT` (`RED_PACKET_ACCOUNT_ID`,`BALANCE_AMOUNT`,`USER_ID`) VALUES (1,100000,1000); +INSERT INTO `RED_RED_PACKET_ACCOUNT` (`RED_PACKET_ACCOUNT_ID`,`BALANCE_AMOUNT`,`USER_ID`) VALUES (2,100000,2000); From 199043f252ac053ec6d5468c643b2db1bf96116a Mon Sep 17 00:00:00 2001 From: "changming.xie" <> Date: Wed, 4 Aug 2021 20:20:25 +0800 Subject: [PATCH 3/5] fix sample error. --- .../java/org/mengyun/tcctransaction/api/Compensable.java | 2 +- .../java/org/mengyun/tcctransaction/api/EnableTcc.java | 9 ++++++++- .../api/ParameterTransactionContextEditor.java | 6 ++++-- .../dubbo/filter/CompensableTransactionFilter.java | 2 +- .../dubbo/filter/DubboInvokeProceedingJoinPoint.java | 7 +++++-- .../capital/service/CapitalTradeOrderServiceImpl.java | 2 +- .../service/RedPacketTradeOrderServiceImpl.java | 2 +- 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java index a5db0a66..04d05e52 100644 --- a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/Compensable.java @@ -22,5 +22,5 @@ public boolean asyncCancel() default false; - public Class transactionContextEditor() default ParameterTransactionContextEditor.class; + public Class transactionContextEditor() default NullableTransactionContextEditor.class; } \ No newline at end of file diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java index 05463292..f870b4a8 100644 --- a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/EnableTcc.java @@ -1,5 +1,12 @@ package org.mengyun.tcctransaction.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) public @interface EnableTcc { - public Class transactionContextEditor() default NullableTransactionContextEditor.class; } diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java index 95ca2852..943688fc 100644 --- a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java @@ -37,9 +37,9 @@ public TransactionContext get(Object target, Method method, Object[] args) { if (position >= 0) { return (TransactionContext) args[position]; + } else { + throw new RuntimeException("No TransactionContext parameter exist while get TransactionContext with ParameterTransactionContextEditor!"); } - - return null; } @Override @@ -48,6 +48,8 @@ public void set(TransactionContext transactionContext, Object target, Method met int position = getTransactionContextParamPosition(method.getParameterTypes()); if (position >= 0) { args[position] = transactionContext; + } else { + throw new RuntimeException("No TransactionContext parameter exist while set TransactionContext with ParameterTransactionContextEditor!"); } } } diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java index a75d711c..bec5e910 100644 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java @@ -40,7 +40,7 @@ private Result doInvoke(Invoker invoker, Invocation invocation) { EnableTcc enableTcc = method.getAnnotation(EnableTcc.class); if (enableTcc != null) { - DubboInvokeProceedingJoinPoint pjp = new DubboInvokeProceedingJoinPoint(invocation, null, DubboTransactionContextEditor.class); + DubboInvokeProceedingJoinPoint pjp = new DubboInvokeProceedingJoinPoint(invoker, invocation, null, DubboTransactionContextEditor.class); return (Result) FactoryBuilder.factoryOf(ResourceCoordinatorAspect.class).getInstance().interceptTransactionContextMethod(pjp); } else { return invoker.invoke(invocation); diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java index ed8cdff1..acfe8772 100644 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/DubboInvokeProceedingJoinPoint.java @@ -2,6 +2,7 @@ import org.apache.dubbo.rpc.Constants; import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.model.ConsumerMethodModel; import org.apache.dubbo.rpc.model.ConsumerModel; import org.mengyun.tcctransaction.api.Compensable; @@ -12,11 +13,13 @@ public class DubboInvokeProceedingJoinPoint implements TransactionMethodJoinPoint { + private Invoker invoker; private Invocation invocation; Compensable compensable; Class transactionContextEditorClass; - public DubboInvokeProceedingJoinPoint(Invocation invocation, Compensable compensable, Class transactionContextEditorClass) { + public DubboInvokeProceedingJoinPoint(Invoker invoker, Invocation invocation, Compensable compensable, Class transactionContextEditorClass) { + this.invoker = invoker; this.invocation = invocation; this.compensable = compensable; this.transactionContextEditorClass = transactionContextEditorClass; @@ -54,7 +57,7 @@ public Object[] getArgs() { @Override public Object proceed() throws Throwable { - return invocation.getInvoker().invoke(invocation); + return invoker.invoke(invocation); } @Override diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java index 912c7165..5872dc48 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java +++ b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/java/org/mengyun/tcctransaction/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java @@ -29,7 +29,7 @@ public class CapitalTradeOrderServiceImpl implements CapitalTradeOrderService { TradeOrderRepository tradeOrderRepository; @Override - @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord") + @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord", transactionContextEditor = DubboTransactionContextEditor.class) @Transactional public String record(CapitalTradeOrderDto tradeOrderDto) { diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java index b38b3692..bde93d18 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java +++ b/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/java/org/mengyun/tcctransaction/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java @@ -29,7 +29,7 @@ public class RedPacketTradeOrderServiceImpl implements RedPacketTradeOrderServic TradeOrderRepository tradeOrderRepository; @Override - @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord") + @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord", transactionContextEditor = DubboTransactionContextEditor.class) @Transactional public String record(RedPacketTradeOrderDto tradeOrderDto) { From 550001679b5a84e95c5aa96872bc751bc3ac902e Mon Sep 17 00:00:00 2001 From: "changming.xie" <> Date: Thu, 5 Aug 2021 11:56:52 +0800 Subject: [PATCH 4/5] update the TransactionContextEditor --- .../MethodTransactionContextEditor.java | 35 ------------------- .../ResourceCoordinatorInterceptor.java | 1 - .../RedPacketTradeOrderServiceImpl.java | 1 - 3 files changed, 37 deletions(-) delete mode 100644 tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/context/MethodTransactionContextEditor.java diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/context/MethodTransactionContextEditor.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/context/MethodTransactionContextEditor.java deleted file mode 100644 index f48fa1c9..00000000 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/context/MethodTransactionContextEditor.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.mengyun.tcctransaction.context; - -import org.mengyun.tcctransaction.api.TransactionContext; -import org.mengyun.tcctransaction.api.TransactionContextEditor; -import org.mengyun.tcctransaction.utils.CompensableMethodUtils; - -import java.lang.reflect.Method; - -/** - * Created by changming.xie on 1/18/17. - * this class is replaced by org.mengyun.tcctransaction.api.Compensable.DefaultTransactionContextEditor - */ -@Deprecated -public class MethodTransactionContextEditor implements TransactionContextEditor { - - @Override - public TransactionContext get(Object target, Method method, Object[] args) { - int position = CompensableMethodUtils.getTransactionContextParamPosition(method.getParameterTypes()); - - if (position >= 0) { - return (TransactionContext) args[position]; - } - - return null; - } - - @Override - public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) { - - int position = CompensableMethodUtils.getTransactionContextParamPosition(method.getParameterTypes()); - if (position >= 0) { - args[position] = transactionContext; - } - } -} diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java index c4aa64f1..628e36af 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java @@ -16,7 +16,6 @@ public class ResourceCoordinatorInterceptor { private TransactionManager transactionManager; - public void setTransactionManager(TransactionManager transactionManager) { this.transactionManager = transactionManager; } diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/java/org/mengyun/tcctransaction/sample/http/redpacket/service/RedPacketTradeOrderServiceImpl.java b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/java/org/mengyun/tcctransaction/sample/http/redpacket/service/RedPacketTradeOrderServiceImpl.java index 9d707ac1..0d90a978 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/java/org/mengyun/tcctransaction/sample/http/redpacket/service/RedPacketTradeOrderServiceImpl.java +++ b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/java/org/mengyun/tcctransaction/sample/http/redpacket/service/RedPacketTradeOrderServiceImpl.java @@ -3,7 +3,6 @@ import org.apache.commons.lang3.time.DateFormatUtils; import org.mengyun.tcctransaction.api.Compensable; import org.mengyun.tcctransaction.api.TransactionContext; -import org.mengyun.tcctransaction.context.MethodTransactionContextEditor; import org.mengyun.tcctransaction.sample.http.redpacket.api.RedPacketTradeOrderService; import org.mengyun.tcctransaction.sample.http.redpacket.api.dto.RedPacketTradeOrderDto; import org.mengyun.tcctransaction.sample.redpacket.domain.entity.RedPacketAccount; From af7b32f278e65e41db024555133b323f718849a2 Mon Sep 17 00:00:00 2001 From: "changming.xie" <> Date: Thu, 5 Aug 2021 15:16:00 +0800 Subject: [PATCH 5/5] update the tcc transaction dubbo, remove tccJavassist and tccJdk. --- pom.xml | 2 +- tcc-transaction-admin-web/src/App.js | 3 +- tcc-transaction-admin-web/src/App.test.js | 3 +- .../src/common/constants.js | 1 - .../src/components/DeletedKey.js | 9 +- .../src/components/Normal.js | 7 +- .../src/components/SearchBox.js | 8 +- tcc-transaction-admin-web/src/index.js | 1 - .../src/pages/agg/Degrade.js | 12 +- .../src/pages/agg/Normal.js | 6 +- .../src/pages/agg/index.js | 7 +- .../src/pages/agg/modal.js | 2 +- .../src/pages/tcc/Degrade.js | 10 +- .../src/pages/tcc/domain/DrawerDomainList.jsx | 6 +- .../src/pages/tcc/domain/SearchBox.jsx | 2 +- .../src/pages/tcc/domain/index.jsx | 2 +- .../src/pages/tcc/index.js | 5 +- .../ParameterTransactionContextEditor.java | 4 + .../CompensableTransactionAspect.java | 24 +- .../CompensableTransactionInterceptor.java | 1 - .../ResourceCoordinatorAspect.java | 24 +- .../filter/CompensableTransactionFilter.java | 11 +- .../proxy/javassist/TccClassGenerator.java | 328 ------------------ .../javassist/TccJavassistProxyFactory.java | 16 - .../dubbo/proxy/javassist/TccProxy.java | 264 -------------- .../proxy/jdk/MethodProceedingJoinPoint.java | 258 -------------- .../jdk/TccInvokerInvocationHandler.java | 54 --- .../dubbo/proxy/jdk/TccJdkProxyFactory.java | 23 -- .../dubbo/##org.apache.dubbo.rpc.ProxyFactory | 2 - .../main/resources/tcc-transaction-dubbo.xml | 8 - .../spring/local/appcontext-service-tcc.xml | 3 +- .../spring/local/appcontext-service-tcc.xml | 3 +- .../spring/local/appcontext-service-tcc.xml | 3 +- 33 files changed, 89 insertions(+), 1023 deletions(-) delete mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccClassGenerator.java delete mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccJavassistProxyFactory.java delete mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccProxy.java delete mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/MethodProceedingJoinPoint.java delete mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java delete mode 100644 tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccJdkProxyFactory.java delete mode 100644 tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/##org.apache.dubbo.rpc.ProxyFactory delete mode 100644 tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml diff --git a/pom.xml b/pom.xml index 2942b7b0..42032fec 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.8 - 1.6.3 + 1.7.0 UTF-8 ${java.version} ${java.version} diff --git a/tcc-transaction-admin-web/src/App.js b/tcc-transaction-admin-web/src/App.js index 5d5b1db5..a0e927c0 100644 --- a/tcc-transaction-admin-web/src/App.js +++ b/tcc-transaction-admin-web/src/App.js @@ -1,7 +1,6 @@ -import React from 'react'; import {Provider} from 'react-redux'; import {Layout, Menu} from 'antd'; -import {Link, BrowserRouter as Router, Route, Switch} from 'react-router-dom'; +import {BrowserRouter as Router, Link, Route, Switch} from 'react-router-dom'; import 'antd/dist/antd.css'; import './App.css'; import Domain from './pages/tcc/domain/index'; diff --git a/tcc-transaction-admin-web/src/App.test.js b/tcc-transaction-admin-web/src/App.test.js index 4db7ebc2..11bd5272 100644 --- a/tcc-transaction-admin-web/src/App.test.js +++ b/tcc-transaction-admin-web/src/App.test.js @@ -1,5 +1,4 @@ -import React from 'react'; -import { render } from '@testing-library/react'; +import {render} from '@testing-library/react'; import App from './App'; test('renders learn react link', () => { diff --git a/tcc-transaction-admin-web/src/common/constants.js b/tcc-transaction-admin-web/src/common/constants.js index 29a6f19a..0a39b58b 100644 --- a/tcc-transaction-admin-web/src/common/constants.js +++ b/tcc-transaction-admin-web/src/common/constants.js @@ -1,4 +1,3 @@ -import React from 'react'; import {Button, Modal} from 'antd'; import ReactJson from 'react-json-view'; diff --git a/tcc-transaction-admin-web/src/components/DeletedKey.js b/tcc-transaction-admin-web/src/components/DeletedKey.js index e166a89c..c938e60e 100644 --- a/tcc-transaction-admin-web/src/components/DeletedKey.js +++ b/tcc-transaction-admin-web/src/components/DeletedKey.js @@ -1,7 +1,6 @@ -import React from 'react'; -import { Space, Table, Button } from 'antd'; -import { columns as originColumns } from '../common/constants'; -import { restore } from '../common/api'; +import {Button, Space, Table} from 'antd'; +import {columns as originColumns} from '../common/constants'; +import {restore} from '../common/api'; const columns = originColumns.concat({ title: 'Operation', @@ -31,4 +30,4 @@ const DeletedKey = ({ data }) => { } -export default DeletedKey; \ No newline at end of file +export default DeletedKey; diff --git a/tcc-transaction-admin-web/src/components/Normal.js b/tcc-transaction-admin-web/src/components/Normal.js index f5a2563e..a858813d 100644 --- a/tcc-transaction-admin-web/src/components/Normal.js +++ b/tcc-transaction-admin-web/src/components/Normal.js @@ -1,6 +1,5 @@ -import React from 'react'; -import { Button, Table, Space } from 'antd'; -import { columns as originColumns } from '../common/constants'; +import {Button, Space, Table} from 'antd'; +import {columns as originColumns} from '../common/constants'; import * as api from '../common/api'; const columns = originColumns.concat({ @@ -50,4 +49,4 @@ const Normal = ({ data }) => { ) } -export default Normal \ No newline at end of file +export default Normal diff --git a/tcc-transaction-admin-web/src/components/SearchBox.js b/tcc-transaction-admin-web/src/components/SearchBox.js index ff988bc3..c22fac0f 100644 --- a/tcc-transaction-admin-web/src/components/SearchBox.js +++ b/tcc-transaction-admin-web/src/components/SearchBox.js @@ -1,5 +1,5 @@ -import React, { useState } from 'react'; -import { Button, Cascader } from 'antd'; +import {useState} from 'react'; +import {Button, Cascader} from 'antd'; const SearchBox = ({ onChange, @@ -13,7 +13,7 @@ const SearchBox = ({ }; const handleAdd = () => {} - + return (
{ const [domains, setDomains] = useState([]); @@ -36,7 +36,7 @@ const Page = () => { return ( <>
- + Domain 状态 @@ -65,10 +65,10 @@ const Page = () => { }
- +
) } -export default Page; \ No newline at end of file +export default Page; diff --git a/tcc-transaction-admin-web/src/pages/agg/Normal.js b/tcc-transaction-admin-web/src/pages/agg/Normal.js index 28594b21..7fb8ae8f 100644 --- a/tcc-transaction-admin-web/src/pages/agg/Normal.js +++ b/tcc-transaction-admin-web/src/pages/agg/Normal.js @@ -1,5 +1,5 @@ -import React, { useEffect, useState } from 'react'; -import { Table, Button, Cascader, Modal, message, Form } from 'antd'; +import {useEffect, useState} from 'react'; +import {Button, Cascader, Form, message, Modal, Table} from 'antd'; import ReactJson from 'react-json-view'; import * as api from '../../api/agg'; import CreateModal from './modal'; @@ -202,4 +202,4 @@ const Normal = () => { ); } -export default Normal; \ No newline at end of file +export default Normal; diff --git a/tcc-transaction-admin-web/src/pages/agg/index.js b/tcc-transaction-admin-web/src/pages/agg/index.js index 235864ac..3816966b 100644 --- a/tcc-transaction-admin-web/src/pages/agg/index.js +++ b/tcc-transaction-admin-web/src/pages/agg/index.js @@ -1,6 +1,5 @@ -import React from 'react'; -import { Layout, Menu } from 'antd'; -import { Switch, Route, Link } from 'react-router-dom'; +import {Layout, Menu} from 'antd'; +import {Link, Route, Switch} from 'react-router-dom'; import Normal from './Normal'; import Degrade from './Degrade'; @@ -31,4 +30,4 @@ const Page = () => ( ) -export default Page; \ No newline at end of file +export default Page; diff --git a/tcc-transaction-admin-web/src/pages/agg/modal.js b/tcc-transaction-admin-web/src/pages/agg/modal.js index 65e8e406..51121660 100644 --- a/tcc-transaction-admin-web/src/pages/agg/modal.js +++ b/tcc-transaction-admin-web/src/pages/agg/modal.js @@ -1,5 +1,5 @@ import React from "react"; -import { Form, Input, message, Modal } from "antd"; +import {Form, Input, message, Modal} from "antd"; import * as api from "../../api/agg"; diff --git a/tcc-transaction-admin-web/src/pages/tcc/Degrade.js b/tcc-transaction-admin-web/src/pages/tcc/Degrade.js index d6aaff0c..987a1bca 100644 --- a/tcc-transaction-admin-web/src/pages/tcc/Degrade.js +++ b/tcc-transaction-admin-web/src/pages/tcc/Degrade.js @@ -1,6 +1,6 @@ -import React, { useState, useEffect } from 'react'; -import { Switch, Row, Col, Divider } from 'antd'; -import { getDegradeList, degrade } from '../../common/api'; +import {useEffect, useState} from 'react'; +import {Col, Divider, Row, Switch} from 'antd'; +import {degrade, getDegradeList} from '../../common/api'; const Page = () => { const [domains, setDomains] = useState([]); @@ -64,10 +64,10 @@ const Page = () => { }
- +
) } -export default Page; \ No newline at end of file +export default Page; diff --git a/tcc-transaction-admin-web/src/pages/tcc/domain/DrawerDomainList.jsx b/tcc-transaction-admin-web/src/pages/tcc/domain/DrawerDomainList.jsx index c1249f74..62cc4182 100644 --- a/tcc-transaction-admin-web/src/pages/tcc/domain/DrawerDomainList.jsx +++ b/tcc-transaction-admin-web/src/pages/tcc/domain/DrawerDomainList.jsx @@ -1,8 +1,8 @@ import React from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { Domain } from "../../../store/actions/domain"; +import {useDispatch, useSelector} from "react-redux"; +import {Domain} from "../../../store/actions/domain"; import * as api from "../../../common/api"; -import { Row, Col, Button, Popconfirm, message } from "antd"; +import {Button, Col, message, Popconfirm, Row} from "antd"; const DrawerDomainList = () => { const { domainData } = useSelector( diff --git a/tcc-transaction-admin-web/src/pages/tcc/domain/SearchBox.jsx b/tcc-transaction-admin-web/src/pages/tcc/domain/SearchBox.jsx index df641ce0..91f5aca7 100644 --- a/tcc-transaction-admin-web/src/pages/tcc/domain/SearchBox.jsx +++ b/tcc-transaction-admin-web/src/pages/tcc/domain/SearchBox.jsx @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import {Button, Form, Select, Drawer} from 'antd'; +import {Button, Drawer, Form, Select} from 'antd'; import {useDispatch, useSelector} from 'react-redux'; import {Domain} from '../../../store/actions/domain'; import DrawerDomainList from './DrawerDomainList'; diff --git a/tcc-transaction-admin-web/src/pages/tcc/domain/index.jsx b/tcc-transaction-admin-web/src/pages/tcc/domain/index.jsx index 4d03ffe5..0075d4e3 100644 --- a/tcc-transaction-admin-web/src/pages/tcc/domain/index.jsx +++ b/tcc-transaction-admin-web/src/pages/tcc/domain/index.jsx @@ -1,4 +1,4 @@ -import React, {useState, useEffect} from 'react'; +import React, {useEffect, useState} from 'react'; import {Tabs} from 'antd'; import * as api from '../../../common/api'; import SearchBox from './SearchBox'; diff --git a/tcc-transaction-admin-web/src/pages/tcc/index.js b/tcc-transaction-admin-web/src/pages/tcc/index.js index 70cee716..1ab9717f 100644 --- a/tcc-transaction-admin-web/src/pages/tcc/index.js +++ b/tcc-transaction-admin-web/src/pages/tcc/index.js @@ -1,6 +1,5 @@ -import React from 'react'; -import { Layout, Menu } from 'antd'; -import { Switch, Route, Link } from 'react-router-dom'; +import {Layout, Menu} from 'antd'; +import {Link, Route, Switch} from 'react-router-dom'; // @ts-ignore import Domain from './domain'; import Degrade from './Degrade'; diff --git a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java index 943688fc..8347594f 100644 --- a/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java +++ b/tcc-transaction-api/src/main/java/org/mengyun/tcctransaction/api/ParameterTransactionContextEditor.java @@ -17,6 +17,10 @@ public static int getTransactionContextParamPosition(Class[] parameterTypes) return position; } + public static boolean hasTransactionContextParameter(Class[] parameterTypes) { + return getTransactionContextParamPosition(parameterTypes) >= 0; + } + public static TransactionContext getTransactionContextFromArgs(Object[] args) { TransactionContext transactionContext = null; diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java index e7b79ea0..1e5d1da9 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionAspect.java @@ -6,6 +6,11 @@ import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.NullableTransactionContextEditor; +import org.mengyun.tcctransaction.api.ParameterTransactionContextEditor; +import org.mengyun.tcctransaction.api.TransactionContextEditor; + +import java.lang.reflect.Method; /** * Created by changmingxie on 10/30/15. @@ -27,8 +32,23 @@ public void compensableTransactionPointcut() { @Around("compensableTransactionPointcut()") public Object interceptCompensableMethod(ProceedingJoinPoint pjp) throws Throwable { - Compensable compensable = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Compensable.class); - return compensableTransactionInterceptor.interceptCompensableMethod(new AspectJTransactionMethodJoinPoint(pjp, compensable, compensable.transactionContextEditor())); + Method method = ((MethodSignature) pjp.getSignature()).getMethod(); + + Compensable compensable = method.getAnnotation(Compensable.class); + + Class transactionContextEditor = NullableTransactionContextEditor.class; + + if (compensable != null) { + transactionContextEditor = compensable.transactionContextEditor(); + } + + if (transactionContextEditor.equals(NullableTransactionContextEditor.class) + && ParameterTransactionContextEditor.hasTransactionContextParameter(method.getParameterTypes())) { + + transactionContextEditor = ParameterTransactionContextEditor.class; + } + + return compensableTransactionInterceptor.interceptCompensableMethod(new AspectJTransactionMethodJoinPoint(pjp, compensable, transactionContextEditor)); } public abstract int getOrder(); diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java index f6ef1504..dbc226d6 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java @@ -1,7 +1,6 @@ package org.mengyun.tcctransaction.interceptor; import com.alibaba.fastjson.JSON; -import org.aspectj.lang.ProceedingJoinPoint; import org.mengyun.tcctransaction.IllegalTransactionStatusException; import org.mengyun.tcctransaction.NoExistedTransactionException; import org.mengyun.tcctransaction.Transaction; diff --git a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java index 458e0f33..82f7be2e 100644 --- a/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java +++ b/tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorAspect.java @@ -6,7 +6,11 @@ import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.mengyun.tcctransaction.api.Compensable; +import org.mengyun.tcctransaction.api.NullableTransactionContextEditor; import org.mengyun.tcctransaction.api.ParameterTransactionContextEditor; +import org.mengyun.tcctransaction.api.TransactionContextEditor; + +import java.lang.reflect.Method; /** * Created by changmingxie on 11/8/15. @@ -24,12 +28,24 @@ public void transactionResourcePointcut() { @Around("transactionResourcePointcut()") public Object interceptTransactionResourceMethodWithCompensableAnnotation(ProceedingJoinPoint pjp) throws Throwable { - Compensable compensable = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Compensable.class); + + Method method = ((MethodSignature) pjp.getSignature()).getMethod(); + + Compensable compensable = method.getAnnotation(Compensable.class); + + Class transactionContextEditor = NullableTransactionContextEditor.class; + if (compensable != null) { - return interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp, compensable, compensable.transactionContextEditor())); - } else { - return interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp, null, ParameterTransactionContextEditor.class)); + transactionContextEditor = compensable.transactionContextEditor(); } + + if (transactionContextEditor.equals(NullableTransactionContextEditor.class) + && ParameterTransactionContextEditor.hasTransactionContextParameter(method.getParameterTypes())) { + + transactionContextEditor = ParameterTransactionContextEditor.class; + } + + return interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp, compensable, transactionContextEditor)); } public Object interceptTransactionContextMethod(TransactionMethodJoinPoint pjp) throws Throwable { diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java index bec5e910..0d3adcad 100644 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java +++ b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/filter/CompensableTransactionFilter.java @@ -17,22 +17,13 @@ public class CompensableTransactionFilter implements Filter { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - -// return invoker.invoke(invocation); - return doInvoke(invoker, invocation); - } - - private Result doInvoke(Invoker invoker, Invocation invocation) { - Method method = null; try { method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()); - boolean hasTransactionContextParameter = ParameterTransactionContextEditor.getTransactionContextParamPosition(invocation.getParameterTypes()) > 0; - - if (hasTransactionContextParameter) { + if (ParameterTransactionContextEditor.hasTransactionContextParameter(invocation.getParameterTypes())) { // in this case, will handler by ResourceCoordinatorAspect return invoker.invoke(invocation); } diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccClassGenerator.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccClassGenerator.java deleted file mode 100644 index 0e065380..00000000 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccClassGenerator.java +++ /dev/null @@ -1,328 +0,0 @@ -package org.mengyun.tcctransaction.dubbo.proxy.javassist; - -import javassist.*; -import javassist.bytecode.AnnotationsAttribute; -import javassist.bytecode.ConstPool; -import javassist.bytecode.annotation.Annotation; -import javassist.bytecode.annotation.ClassMemberValue; -import javassist.bytecode.annotation.EnumMemberValue; -import javassist.bytecode.annotation.StringMemberValue; -import org.apache.dubbo.common.utils.ReflectUtils; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Created by changming.xie on 1/14/17. - */ - -public final class TccClassGenerator { - private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(0); - private static final String SIMPLE_NAME_TAG = ""; - private static final Map POOL_MAP = new ConcurrentHashMap(); //ClassLoader - ClassPool - private ClassPool mPool; - private CtClass mCtc; - private String mClassName, mSuperClass; - private Set mInterfaces; - private List mFields, mConstructors, mMethods; - private Set compensableMethods = new HashSet(); - private Map mCopyMethods; // - private Map> mCopyConstructors; // - private boolean mDefaultConstructor = false; - - private TccClassGenerator() { - } - - private TccClassGenerator(ClassPool pool) { - mPool = pool; - } - - public static TccClassGenerator newInstance() { - return new TccClassGenerator(getClassPool(Thread.currentThread().getContextClassLoader())); - } - - public static TccClassGenerator newInstance(ClassLoader loader) { - return new TccClassGenerator(getClassPool(loader)); - } - - public static boolean isDynamicClass(Class cl) { - return TccClassGenerator.DC.class.isAssignableFrom(cl); - } - - public static ClassPool getClassPool(ClassLoader loader) { - if (loader == null) - return ClassPool.getDefault(); - - ClassPool pool = POOL_MAP.get(loader); - if (pool == null) { - pool = new ClassPool(true); - pool.appendClassPath(new LoaderClassPath(loader)); - POOL_MAP.put(loader, pool); - } - return pool; - } - - private static String modifier(int mod) { - if (java.lang.reflect.Modifier.isPublic(mod)) return "public"; - if (java.lang.reflect.Modifier.isProtected(mod)) return "protected"; - if (java.lang.reflect.Modifier.isPrivate(mod)) return "private"; - return ""; - } - - public String getClassName() { - return mClassName; - } - - public TccClassGenerator setClassName(String name) { - mClassName = name; - return this; - } - - public TccClassGenerator addInterface(String cn) { - if (mInterfaces == null) - mInterfaces = new HashSet(); - mInterfaces.add(cn); - return this; - } - - public TccClassGenerator addInterface(Class cl) { - return addInterface(cl.getName()); - } - - public TccClassGenerator setSuperClass(String cn) { - mSuperClass = cn; - return this; - } - - public TccClassGenerator setSuperClass(Class cl) { - mSuperClass = cl.getName(); - return this; - } - - public TccClassGenerator addField(String code) { - if (mFields == null) - mFields = new ArrayList(); - mFields.add(code); - return this; - } - - public TccClassGenerator addField(String name, int mod, Class type) { - return addField(name, mod, type, null); - } - - public TccClassGenerator addField(String name, int mod, Class type, String def) { - StringBuilder sb = new StringBuilder(); - sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(type)).append(' '); - sb.append(name); - if (def != null && def.length() > 0) { - sb.append('='); - sb.append(def); - } - sb.append(';'); - return addField(sb.toString()); - } - - public TccClassGenerator addMethod(String code) { - if (mMethods == null) - mMethods = new ArrayList(); - mMethods.add(code); - return this; - } - - public TccClassGenerator addMethod(String name, int mod, Class rt, Class[] pts, String body) { - return addMethod(false, name, mod, rt, pts, null, body); - } - - public TccClassGenerator addMethod(boolean isCompensableMethod, String name, int mod, Class rt, Class[] pts, Class[] ets, String body) { - StringBuilder sb = new StringBuilder(); - - sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(rt)).append(' ').append(name); - sb.append('('); - for (int i = 0; i < pts.length; i++) { - if (i > 0) - sb.append(','); - sb.append(ReflectUtils.getName(pts[i])); - sb.append(" arg").append(i); - } - sb.append(')'); - if (ets != null && ets.length > 0) { - sb.append(" throws "); - for (int i = 0; i < ets.length; i++) { - if (i > 0) - sb.append(','); - sb.append(ReflectUtils.getName(ets[i])); - } - } - sb.append('{').append(body).append('}'); - - if (isCompensableMethod) { - compensableMethods.add(sb.toString()); - } - - return addMethod(sb.toString()); - } - - public TccClassGenerator addMethod(Method m) { - addMethod(m.getName(), m); - return this; - } - - public TccClassGenerator addMethod(String name, Method m) { - String desc = name + ReflectUtils.getDescWithoutMethodName(m); - addMethod(':' + desc); - if (mCopyMethods == null) - mCopyMethods = new ConcurrentHashMap(8); - mCopyMethods.put(desc, m); - return this; - } - - public TccClassGenerator addConstructor(String code) { - if (mConstructors == null) - mConstructors = new LinkedList(); - mConstructors.add(code); - return this; - } - - public TccClassGenerator addConstructor(int mod, Class[] pts, String body) { - return addConstructor(mod, pts, null, body); - } - - public TccClassGenerator addConstructor(int mod, Class[] pts, Class[] ets, String body) { - StringBuilder sb = new StringBuilder(); - sb.append(modifier(mod)).append(' ').append(SIMPLE_NAME_TAG); - sb.append('('); - for (int i = 0; i < pts.length; i++) { - if (i > 0) - sb.append(','); - sb.append(ReflectUtils.getName(pts[i])); - sb.append(" arg").append(i); - } - sb.append(')'); - if (ets != null && ets.length > 0) { - sb.append(" throws "); - for (int i = 0; i < ets.length; i++) { - if (i > 0) - sb.append(','); - sb.append(ReflectUtils.getName(ets[i])); - } - } - sb.append('{').append(body).append('}'); - return addConstructor(sb.toString()); - } - - public TccClassGenerator addConstructor(Constructor c) { - String desc = ReflectUtils.getDesc(c); - addConstructor(":" + desc); - if (mCopyConstructors == null) - mCopyConstructors = new ConcurrentHashMap>(4); - mCopyConstructors.put(desc, c); - return this; - } - - public TccClassGenerator addDefaultConstructor() { - mDefaultConstructor = true; - return this; - } - - public ClassPool getClassPool() { - return mPool; - } - - public Class toClass() { - if (mCtc != null) - mCtc.detach(); - long id = CLASS_NAME_COUNTER.getAndIncrement(); - try { - CtClass ctcs = mSuperClass == null ? null : mPool.get(mSuperClass); - if (mClassName == null) - mClassName = (mSuperClass == null || javassist.Modifier.isPublic(ctcs.getModifiers()) - ? TccClassGenerator.class.getName() : mSuperClass + "$sc") + id; - mCtc = mPool.makeClass(mClassName); - if (mSuperClass != null) - mCtc.setSuperclass(ctcs); - mCtc.addInterface(mPool.get(DC.class.getName())); // add dynamic class tag. - if (mInterfaces != null) - for (String cl : mInterfaces) mCtc.addInterface(mPool.get(cl)); - if (mFields != null) - for (String code : mFields) mCtc.addField(CtField.make(code, mCtc)); - if (mMethods != null) { - for (String code : mMethods) { - if (code.charAt(0) == ':') - mCtc.addMethod(CtNewMethod.copy(getCtMethod(mCopyMethods.get(code.substring(1))), code.substring(1, code.indexOf('(')), mCtc, null)); - else { - - CtMethod ctMethod = CtNewMethod.make(code, mCtc); - - if (compensableMethods.contains(code)) { - - ConstPool constpool = mCtc.getClassFile().getConstPool(); - AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag); - Annotation annot = new Annotation("org.mengyun.tcctransaction.api.Compensable", constpool); - EnumMemberValue enumMemberValue = new EnumMemberValue(constpool); - enumMemberValue.setType("org.mengyun.tcctransaction.api.Propagation"); - enumMemberValue.setValue("SUPPORTS"); - annot.addMemberValue("propagation", enumMemberValue); - annot.addMemberValue("confirmMethod", new StringMemberValue(ctMethod.getName(), constpool)); - annot.addMemberValue("cancelMethod", new StringMemberValue(ctMethod.getName(), constpool)); - - ClassMemberValue classMemberValue = new ClassMemberValue("org.mengyun.tcctransaction.dubbo.context.DubboTransactionContextEditor", constpool); - annot.addMemberValue("transactionContextEditor", classMemberValue); - - attr.addAnnotation(annot); - ctMethod.getMethodInfo().addAttribute(attr); - } - - mCtc.addMethod(ctMethod); - } - } - } - if (mDefaultConstructor) - mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc)); - if (mConstructors != null) { - for (String code : mConstructors) { - if (code.charAt(0) == ':') { - mCtc.addConstructor(CtNewConstructor.copy(getCtConstructor(mCopyConstructors.get(code.substring(1))), mCtc, null)); - } else { - String[] sn = mCtc.getSimpleName().split("\\$+"); // inner class name include $. - mCtc.addConstructor(CtNewConstructor.make(code.replaceFirst(SIMPLE_NAME_TAG, sn[sn.length - 1]), mCtc)); - } - } - } - return mCtc.toClass(); - } catch (RuntimeException e) { - throw e; - } catch (NotFoundException e) { - throw new RuntimeException(e.getMessage(), e); - } catch (CannotCompileException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - public void release() { - if (mCtc != null) mCtc.detach(); - if (mInterfaces != null) mInterfaces.clear(); - if (mFields != null) mFields.clear(); - if (mMethods != null) mMethods.clear(); - if (mConstructors != null) mConstructors.clear(); - if (mCopyMethods != null) mCopyMethods.clear(); - if (mCopyConstructors != null) mCopyConstructors.clear(); - } - - private CtClass getCtClass(Class c) throws NotFoundException { - return mPool.get(c.getName()); - } - - private CtMethod getCtMethod(Method m) throws NotFoundException { - return getCtClass(m.getDeclaringClass()).getMethod(m.getName(), ReflectUtils.getDescWithoutMethodName(m)); - } - - private CtConstructor getCtConstructor(Constructor c) throws NotFoundException { - return getCtClass(c.getDeclaringClass()).getConstructor(ReflectUtils.getDesc(c)); - } - - public static interface DC { - } // dynamic class tag interface. -} \ No newline at end of file diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccJavassistProxyFactory.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccJavassistProxyFactory.java deleted file mode 100644 index 5a7f2f18..00000000 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccJavassistProxyFactory.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.mengyun.tcctransaction.dubbo.proxy.javassist; - -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.proxy.InvokerInvocationHandler; -import org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory; - -/** - * Created by changming.xie on 1/14/17. - */ -public class TccJavassistProxyFactory extends JavassistProxyFactory { - - @SuppressWarnings("unchecked") - public T getProxy(Invoker invoker, Class[] interfaces) { - return (T) TccProxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)); - } -} diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccProxy.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccProxy.java deleted file mode 100644 index 431c344a..00000000 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/javassist/TccProxy.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 1999-2011 Alibaba Group. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mengyun.tcctransaction.dubbo.proxy.javassist; - -import org.apache.dubbo.common.utils.ClassHelper; -import org.apache.dubbo.common.utils.ReflectUtils; -import org.mengyun.tcctransaction.api.Compensable; - -import java.lang.ref.Reference; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; - -/** - * TccProxy. - * - * @author qian.lei - */ - -public abstract class TccProxy { - public static final InvocationHandler RETURN_NULL_INVOKER = new InvocationHandler() { - public Object invoke(Object proxy, Method method, Object[] args) { - return null; - } - }; - public static final InvocationHandler THROW_UNSUPPORTED_INVOKER = new InvocationHandler() { - public Object invoke(Object proxy, Method method, Object[] args) { - throw new UnsupportedOperationException("Method [" + ReflectUtils.getName(method) + "] unimplemented."); - } - }; - private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0); - private static final String PACKAGE_NAME = TccProxy.class.getPackage().getName(); - private static final Map> ProxyCacheMap = new WeakHashMap>(); - - private static final Object PendingGenerationMarker = new Object(); - - protected TccProxy() { - } - - /** - * Get proxy. - * - * @param ics interface class array. - * @return TccProxy instance. - */ - public static TccProxy getProxy(Class... ics) { - return getProxy(ClassHelper.getCallerClassLoader(TccProxy.class), ics); - } - - /** - * Get proxy. - * - * @param cl class loader. - * @param ics interface class array. - * @return TccProxy instance. - */ - public static TccProxy getProxy(ClassLoader cl, Class... ics) { - if (ics.length > 65535) - throw new IllegalArgumentException("interface limit exceeded"); - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ics.length; i++) { - String itf = ics[i].getName(); - if (!ics[i].isInterface()) - throw new RuntimeException(itf + " is not a interface."); - - Class tmp = null; - try { - tmp = Class.forName(itf, false, cl); - } catch (ClassNotFoundException e) { - } - - if (tmp != ics[i]) - throw new IllegalArgumentException(ics[i] + " is not visible from class loader"); - - sb.append(itf).append(';'); - } - - // use interface class name list as key. - String key = sb.toString(); - - // get cache by class loader. - Map cache; - synchronized (ProxyCacheMap) { - cache = ProxyCacheMap.get(cl); - if (cache == null) { - cache = new HashMap(); - ProxyCacheMap.put(cl, cache); - } - } - - TccProxy proxy = null; - synchronized (cache) { - do { - Object value = cache.get(key); - if (value instanceof Reference) { - proxy = (TccProxy) ((Reference) value).get(); - if (proxy != null) - return proxy; - } - - if (value == PendingGenerationMarker) { - try { - cache.wait(); - } catch (InterruptedException e) { - } - } else { - cache.put(key, PendingGenerationMarker); - break; - } - } - while (true); - } - - long id = PROXY_CLASS_COUNTER.getAndIncrement(); - String pkg = null; - TccClassGenerator ccp = null, ccm = null; - try { - ccp = TccClassGenerator.newInstance(cl); - - Set worked = new HashSet(); - List methods = new ArrayList(); - - for (int i = 0; i < ics.length; i++) { - if (!Modifier.isPublic(ics[i].getModifiers())) { - String npkg = ics[i].getPackage().getName(); - if (pkg == null) { - pkg = npkg; - } else { - if (!pkg.equals(npkg)) - throw new IllegalArgumentException("non-public interfaces from different packages"); - } - } - ccp.addInterface(ics[i]); - - for (Method method : ics[i].getMethods()) { - String desc = ReflectUtils.getDesc(method); - if (worked.contains(desc)) - continue; - worked.add(desc); - - int ix = methods.size(); - Class rt = method.getReturnType(); - Class[] pts = method.getParameterTypes(); - - StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];"); - for (int j = 0; j < pts.length; j++) - code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(";"); - code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);"); - if (!Void.TYPE.equals(rt)) - code.append(" return ").append(asArgument(rt, "ret")).append(";"); - - methods.add(method); - - StringBuilder compensableDesc = new StringBuilder(); - - Compensable compensable = method.getAnnotation(Compensable.class); - - if (compensable != null) { - ccp.addMethod(true, method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString()); - } else { - ccp.addMethod(false, method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString()); - } - } - } - - if (pkg == null) - pkg = PACKAGE_NAME; - - // create ProxyInstance class. - String pcn = pkg + ".proxy" + id; - ccp.setClassName(pcn); - ccp.addField("public static java.lang.reflect.Method[] methods;"); - ccp.addField("private " + InvocationHandler.class.getName() + " handler;"); - ccp.addConstructor(Modifier.PUBLIC, new Class[]{InvocationHandler.class}, new Class[0], "handler=$1;"); - ccp.addDefaultConstructor(); - Class clazz = ccp.toClass(); - clazz.getField("methods").set(null, methods.toArray(new Method[0])); - - // create TccProxy class. - String fcn = TccProxy.class.getName() + id; - ccm = TccClassGenerator.newInstance(cl); - ccm.setClassName(fcn); - ccm.addDefaultConstructor(); - ccm.setSuperClass(TccProxy.class); - ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }"); - Class pc = ccm.toClass(); - proxy = (TccProxy) pc.newInstance(); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e.getMessage(), e); - } finally { - // release TccClassGenerator - if (ccp != null) - ccp.release(); - if (ccm != null) - ccm.release(); - synchronized (cache) { - if (proxy == null) - cache.remove(key); - else - cache.put(key, new WeakReference(proxy)); - cache.notifyAll(); - } - } - return proxy; - } - - private static String asArgument(Class cl, String name) { - if (cl.isPrimitive()) { - if (Boolean.TYPE == cl) - return name + "==null?false:((Boolean)" + name + ").booleanValue()"; - if (Byte.TYPE == cl) - return name + "==null?(byte)0:((Byte)" + name + ").byteValue()"; - if (Character.TYPE == cl) - return name + "==null?(char)0:((Character)" + name + ").charValue()"; - if (Double.TYPE == cl) - return name + "==null?(double)0:((Double)" + name + ").doubleValue()"; - if (Float.TYPE == cl) - return name + "==null?(float)0:((Float)" + name + ").floatValue()"; - if (Integer.TYPE == cl) - return name + "==null?(int)0:((Integer)" + name + ").intValue()"; - if (Long.TYPE == cl) - return name + "==null?(long)0:((Long)" + name + ").longValue()"; - if (Short.TYPE == cl) - return name + "==null?(short)0:((Short)" + name + ").shortValue()"; - throw new RuntimeException(name + " is unknown primitive type."); - } - return "(" + ReflectUtils.getName(cl) + ")" + name; - } - - /** - * get instance with default handler. - * - * @return instance. - */ - public Object newInstance() { - return newInstance(THROW_UNSUPPORTED_INVOKER); - } - - /** - * get instance with special handler. - * - * @return instance. - */ - abstract public Object newInstance(InvocationHandler handler); -} \ No newline at end of file diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/MethodProceedingJoinPoint.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/MethodProceedingJoinPoint.java deleted file mode 100644 index 9689d00b..00000000 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/MethodProceedingJoinPoint.java +++ /dev/null @@ -1,258 +0,0 @@ -package org.mengyun.tcctransaction.dubbo.proxy.jdk; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.Signature; -import org.aspectj.lang.reflect.MethodSignature; -import org.aspectj.lang.reflect.SourceLocation; -import org.aspectj.runtime.internal.AroundClosure; -import org.mengyun.tcctransaction.SystemException; -import org.mengyun.tcctransaction.utils.ReflectionUtils; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -/** - * Created by changming.xie on 2/26/17. - */ -public class MethodProceedingJoinPoint implements ProceedingJoinPoint, JoinPoint.StaticPart { - - private Object proxy; - - private Object target; - - private Method method; - - private Object[] args; - - private Signature signature; - - /** - * Lazily initialized source location object - */ - private SourceLocation sourceLocation; - - public MethodProceedingJoinPoint(Object proxy, Object target, Method method, Object[] args) { - this.proxy = proxy; - this.target = target; - this.method = method; - this.args = args; - } - - @Override - public void set$AroundClosure(AroundClosure aroundClosure) { - throw new UnsupportedOperationException(); - } - - @Override - public Object proceed() throws Throwable { - - // Use reflection to invoke the method. - try { - ReflectionUtils.makeAccessible(method); - return method.invoke(target, args); - } catch (InvocationTargetException ex) { - // Invoked method threw a checked exception. - // We must rethrow it. The client won't see the interceptor. - throw ex.getTargetException(); - } catch (IllegalArgumentException ex) { - throw new SystemException("Tried calling method [" + - method + "] on target [" + target + "] failed", ex); - } catch (IllegalAccessException ex) { - throw new SystemException("Could not access method [" + method + "]", ex); - } - } - - @Override - public Object proceed(Object[] objects) throws Throwable { - throw new UnsupportedOperationException(); - } - - public String toShortString() { - return "execution(" + getSignature().toShortString() + ")"; - } - - public String toLongString() { - return "execution(" + getSignature().toLongString() + ")"; - } - - public String toString() { - return "execution(" + getSignature().toString() + ")"; - } - - @Override - public Object getThis() { - return this.proxy; - } - - @Override - public Object getTarget() { - return this.target; - } - - @Override - public Object[] getArgs() { - return this.args; - } - - @Override - public Signature getSignature() { - if (this.signature == null) { - this.signature = new MethodSignatureImpl(); - } - return signature; - } - - @Override - public SourceLocation getSourceLocation() { - if (this.sourceLocation == null) { - this.sourceLocation = new SourceLocationImpl(); - } - return this.sourceLocation; - } - - @Override - public String getKind() { - return ProceedingJoinPoint.METHOD_EXECUTION; - } - - @Override - public int getId() { - return 0; - } - - @Override - public StaticPart getStaticPart() { - return this; - } - - /** - * Lazily initialized MethodSignature. - */ - private class MethodSignatureImpl implements MethodSignature { - - private volatile String[] parameterNames; - - public String getName() { - return method.getName(); - } - - public int getModifiers() { - return method.getModifiers(); - } - - public Class getDeclaringType() { - return method.getDeclaringClass(); - } - - public String getDeclaringTypeName() { - return method.getDeclaringClass().getName(); - } - - public Class getReturnType() { - return method.getReturnType(); - } - - public Method getMethod() { - return method; - } - - public Class[] getParameterTypes() { - return method.getParameterTypes(); - } - - public String[] getParameterNames() { - throw new UnsupportedOperationException(); - } - - public Class[] getExceptionTypes() { - return method.getExceptionTypes(); - } - - public String toShortString() { - return toString(false, false, false, false); - } - - public String toLongString() { - return toString(true, true, true, true); - } - - public String toString() { - return toString(false, true, false, true); - } - - private String toString(boolean includeModifier, boolean includeReturnTypeAndArgs, - boolean useLongReturnAndArgumentTypeName, boolean useLongTypeName) { - StringBuilder sb = new StringBuilder(); - if (includeModifier) { - sb.append(Modifier.toString(getModifiers())); - sb.append(" "); - } - if (includeReturnTypeAndArgs) { - appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName); - sb.append(" "); - } - appendType(sb, getDeclaringType(), useLongTypeName); - sb.append("."); - sb.append(getMethod().getName()); - sb.append("("); - Class[] parametersTypes = getParameterTypes(); - appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName); - sb.append(")"); - return sb.toString(); - } - - private void appendTypes(StringBuilder sb, Class[] types, - boolean includeArgs, boolean useLongReturnAndArgumentTypeName) { - if (includeArgs) { - for (int size = types.length, i = 0; i < size; i++) { - appendType(sb, types[i], useLongReturnAndArgumentTypeName); - if (i < size - 1) { - sb.append(","); - } - } - } else { - if (types.length != 0) { - sb.append(".."); - } - } - } - - private void appendType(StringBuilder sb, Class type, boolean useLongTypeName) { - if (type.isArray()) { - appendType(sb, type.getComponentType(), useLongTypeName); - sb.append("[]"); - } else { - sb.append(useLongTypeName ? type.getName() : type.getSimpleName()); - } - } - } - - - /** - * Lazily initialized SourceLocation. - */ - private class SourceLocationImpl implements SourceLocation { - - public Class getWithinType() { - if (proxy == null) { - throw new UnsupportedOperationException("No source location joinpoint available: target is null"); - } - return proxy.getClass(); - } - - public String getFileName() { - throw new UnsupportedOperationException(); - } - - public int getLine() { - throw new UnsupportedOperationException(); - } - - public int getColumn() { - throw new UnsupportedOperationException(); - } - } - -} diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java deleted file mode 100644 index 0712df5c..00000000 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccInvokerInvocationHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.mengyun.tcctransaction.dubbo.proxy.jdk; - -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.proxy.InvokerInvocationHandler; -import org.aspectj.lang.ProceedingJoinPoint; -import org.mengyun.tcctransaction.api.Compensable; -import org.mengyun.tcctransaction.api.Propagation; -import org.mengyun.tcctransaction.dubbo.context.DubboTransactionContextEditor; -import org.mengyun.tcctransaction.interceptor.AspectJTransactionMethodJoinPoint; -import org.mengyun.tcctransaction.interceptor.ResourceCoordinatorAspect; -import org.mengyun.tcctransaction.support.FactoryBuilder; -import org.mengyun.tcctransaction.utils.ReflectionUtils; - -import java.lang.reflect.Method; - -/** - * Created by changming.xie on 2/26/17. - */ -public class TccInvokerInvocationHandler extends InvokerInvocationHandler { - - private Object target; - - public TccInvokerInvocationHandler(Invoker handler) { - super(handler); - } - - public TccInvokerInvocationHandler(T target, Invoker invoker) { - super(invoker); - this.target = target; - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - - Compensable compensable = method.getAnnotation(Compensable.class); - - if (compensable != null) { - - if (StringUtils.isEmpty(compensable.confirmMethod())) { - ReflectionUtils.changeAnnotationValue(compensable, "confirmMethod", method.getName()); - ReflectionUtils.changeAnnotationValue(compensable, "cancelMethod", method.getName()); -// ReflectionUtils.changeAnnotationValue(compensable, "transactionContextEditor", DubboTransactionContextEditor.class); - ReflectionUtils.changeAnnotationValue(compensable, "propagation", Propagation.SUPPORTS); - } - - ProceedingJoinPoint pjp = new MethodProceedingJoinPoint(proxy, target, method, args); - return FactoryBuilder.factoryOf(ResourceCoordinatorAspect.class).getInstance().interceptTransactionContextMethod(new AspectJTransactionMethodJoinPoint(pjp,compensable,DubboTransactionContextEditor.class)); - } else { - return super.invoke(target, method, args); - } - } - - -} diff --git a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccJdkProxyFactory.java b/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccJdkProxyFactory.java deleted file mode 100644 index d5919852..00000000 --- a/tcc-transaction-dubbo/src/main/java/org/mengyun/tcctransaction/dubbo/proxy/jdk/TccJdkProxyFactory.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.mengyun.tcctransaction.dubbo.proxy.jdk; - -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.proxy.InvokerInvocationHandler; -import org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory; - -import java.lang.reflect.Proxy; - -/** - * Created by changming.xie on 2/26/17. - */ -public class TccJdkProxyFactory extends JdkProxyFactory { - - @SuppressWarnings("unchecked") - public T getProxy(Invoker invoker, Class[] interfaces) { - - T proxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker)); - - T tccProxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new TccInvokerInvocationHandler(proxy, invoker)); - - return tccProxy; - } -} \ No newline at end of file diff --git a/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/##org.apache.dubbo.rpc.ProxyFactory b/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/##org.apache.dubbo.rpc.ProxyFactory deleted file mode 100644 index 38765f12..00000000 --- a/tcc-transaction-dubbo/src/main/resources/META-INF/dubbo/##org.apache.dubbo.rpc.ProxyFactory +++ /dev/null @@ -1,2 +0,0 @@ -tccJavassist=org.mengyun.tcctransaction.dubbo.proxy.javassist.TccJavassistProxyFactory -tccJdk=org.mengyun.tcctransaction.dubbo.proxy.jdk.TccJdkProxyFactory \ No newline at end of file diff --git a/tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml b/tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml deleted file mode 100644 index 35c94575..00000000 --- a/tcc-transaction-dubbo/src/main/resources/tcc-transaction-dubbo.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml index 7b2bb6a8..cac7e3cd 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml +++ b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml @@ -1,8 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.tcctransaction.org/schema/tcc http://www.tcctransaction.org/schema/tcc.xsd"> diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml index 59959696..7c7e04bf 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml +++ b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml @@ -1,8 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.tcctransaction.org/schema/tcc http://www.tcctransaction.org/schema/tcc.xsd"> diff --git a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml index 307c5c39..88a1b5f7 100644 --- a/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml +++ b/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transaction-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml @@ -1,8 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.tcctransaction.org/schema/tcc http://www.tcctransaction.org/schema/tcc.xsd">