Commit efea34c87409a5e8e289e83bc46276e7d9793325

Authored by 徐烜
1 parent 799dc67f

添加异步commit,cancel支持

Showing 14 changed files with 196 additions and 25 deletions
tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/TransactionManager.java
@@ -10,6 +10,8 @@ import org.mengyun.tcctransaction.repository.TransactionRepository; @@ -10,6 +10,8 @@ import org.mengyun.tcctransaction.repository.TransactionRepository;
10 import org.slf4j.Logger; 10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
12 12
  13 +import java.util.concurrent.ExecutorService;
  14 +
13 /** 15 /**
14 * Created by changmingxie on 10/26/15. 16 * Created by changmingxie on 10/26/15.
15 * 事务管理器:开始事务,提交事务,回滚事务。 17 * 事务管理器:开始事务,提交事务,回滚事务。
@@ -26,6 +28,12 @@ public class TransactionManager { @@ -26,6 +28,12 @@ public class TransactionManager {
26 this.transactionRepository = transactionRepository; 28 this.transactionRepository = transactionRepository;
27 } 29 }
28 30
  31 + /** 异步执行service */
  32 + private ExecutorService executorService;
  33 + public void setExecutorService(ExecutorService executorService) {
  34 + this.executorService = executorService;
  35 + }
  36 +
29 /** 事务线程局部变量 */ 37 /** 事务线程局部变量 */
30 private ThreadLocal<Transaction> threadLocalTransaction = new ThreadLocal<Transaction>(); 38 private ThreadLocal<Transaction> threadLocalTransaction = new ThreadLocal<Transaction>();
31 public Transaction getCurrentTransaction() { 39 public Transaction getCurrentTransaction() {
@@ -47,14 +55,36 @@ public class TransactionManager { @@ -47,14 +55,36 @@ public class TransactionManager {
47 /** 55 /**
48 * 提交事务. 56 * 提交事务.
49 */ 57 */
50 - public void commit() { 58 + public void commit(boolean asyncCommit) {
51 LOG.debug("==>TransactionManager commit()"); 59 LOG.debug("==>TransactionManager commit()");
52 - Transaction transaction = getCurrentTransaction(); 60 + final Transaction transaction = getCurrentTransaction();
53 61
54 transaction.changeStatus(TransactionStatus.CONFIRMING); 62 transaction.changeStatus(TransactionStatus.CONFIRMING);
55 LOG.debug("==>TransactionManager update transaction status to CONFIRMING"); 63 LOG.debug("==>TransactionManager update transaction status to CONFIRMING");
56 transactionRepository.update(transaction); 64 transactionRepository.update(transaction);
57 65
  66 + if (asyncCommit) {
  67 + try {
  68 + Long statTime = System.currentTimeMillis();
  69 + // TODO:后面会对submit返回的Future做处理
  70 + executorService.submit(new Runnable() {
  71 + @Override
  72 + public void run() {
  73 + commitTransaction(transaction);
  74 + }
  75 + });
  76 + LOG.debug("async submit cost time:" + (System.currentTimeMillis() - statTime));
  77 + } catch (Throwable exp) {
  78 + LOG.warn("compensable transaction async submit confirm failed, recovery job will try to confirm later.", exp);
  79 + throw new ConfirmingException(exp);
  80 + }
  81 + } else {
  82 + commitTransaction(transaction);
  83 + }
  84 +
  85 +
  86 + }
  87 + private void commitTransaction(Transaction transaction) {
58 try { 88 try {
59 LOG.info("==>TransactionManager transaction begin commit()"); 89 LOG.info("==>TransactionManager transaction begin commit()");
60 transaction.commit(); 90 transaction.commit();
@@ -68,13 +98,31 @@ public class TransactionManager { @@ -68,13 +98,31 @@ public class TransactionManager {
68 /** 98 /**
69 * 回滚事务. 99 * 回滚事务.
70 */ 100 */
71 - public void rollback() { 101 + public void rollback(boolean asyncRollback) {
72 LOG.debug("==>TransactionManager rollback()"); 102 LOG.debug("==>TransactionManager rollback()");
73 103
74 - Transaction transaction = getCurrentTransaction(); 104 + final Transaction transaction = getCurrentTransaction();
75 transaction.changeStatus(TransactionStatus.CANCELLING); 105 transaction.changeStatus(TransactionStatus.CANCELLING);
76 transactionRepository.update(transaction); 106 transactionRepository.update(transaction);
77 107
  108 + if (asyncRollback) {
  109 + try {
  110 + executorService.submit(new Runnable() {
  111 + @Override
  112 + public void run() {
  113 + rollbackTransaction(transaction);
  114 + }
  115 + });
  116 + } catch (Throwable exp) {
  117 + LOG.warn("compensable transaction async rollback failed, recovery job will try to rollback later.", exp);
  118 + throw new CancellingException(exp);
  119 + }
  120 + } else {
  121 + rollbackTransaction(transaction);
  122 + }
  123 + }
  124 +
  125 + private void rollbackTransaction(Transaction transaction) {
78 try { 126 try {
79 LOG.info("==>TransactionManager transaction begin rollback()"); 127 LOG.info("==>TransactionManager transaction begin rollback()");
80 transaction.rollback(); 128 transaction.rollback();
tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.java
@@ -54,20 +54,22 @@ public class CompensableTransactionInterceptor { @@ -54,20 +54,22 @@ public class CompensableTransactionInterceptor {
54 54
55 /** 55 /**
56 * 主事务方法的处理. 56 * 主事务方法的处理.
57 - * @param compensableMethodContext 57 + * @param methodContext
58 * @throws Throwable 58 * @throws Throwable
59 */ 59 */
60 - private Object rootMethodProceed(MethodContext compensableMethodContext) throws Throwable { 60 + private Object rootMethodProceed(MethodContext methodContext) throws Throwable {
61 LOG.debug("==>rootMethodProceed"); 61 LOG.debug("==>rootMethodProceed");
  62 + boolean asyncConfirm = methodContext.isAsyncConfirm();
  63 + boolean asyncCancel = methodContext.isAsyncCancel();
62 64
63 TransactionManager transactionManager = transactionConfigurator.getTransactionManager(); 65 TransactionManager transactionManager = transactionConfigurator.getTransactionManager();
64 transactionManager.begin(); // 事务开始(创建事务日志记录,并在当前线程缓存该事务日志记录) 66 transactionManager.begin(); // 事务开始(创建事务日志记录,并在当前线程缓存该事务日志记录)
65 67
66 - Object returnValue = null; // 返回值 68 + Object returnValue; // 返回值
67 try { 69 try {
68 70
69 LOG.debug("==>rootMethodProceed try begin"); 71 LOG.debug("==>rootMethodProceed try begin");
70 - returnValue = compensableMethodContext.proceed(); // Try (开始执行被拦截的方法) 72 + returnValue = methodContext.proceed(); // Try (开始执行被拦截的方法)
71 LOG.debug("==>rootMethodProceed try end"); 73 LOG.debug("==>rootMethodProceed try end");
72 74
73 } catch (OptimisticLockException e) { 75 } catch (OptimisticLockException e) {
@@ -75,25 +77,28 @@ public class CompensableTransactionInterceptor { @@ -75,25 +77,28 @@ public class CompensableTransactionInterceptor {
75 throw e; //do not rollback, waiting for recovery job 77 throw e; //do not rollback, waiting for recovery job
76 } catch (Throwable tryingException) { 78 } catch (Throwable tryingException) {
77 LOG.warn("compensable transaction trying failed.", tryingException); 79 LOG.warn("compensable transaction trying failed.", tryingException);
78 - transactionManager.rollback(); 80 + transactionManager.rollback(asyncCancel);
79 throw tryingException; 81 throw tryingException;
80 } 82 }
81 83
82 LOG.info("===>rootMethodProceed begin commit()"); 84 LOG.info("===>rootMethodProceed begin commit()");
83 - transactionManager.commit(); // Try检验正常后提交(事务管理器在控制提交) 85 + transactionManager.commit(asyncConfirm); // Try检验正常后提交(事务管理器在控制提交)
84 86
85 return returnValue; 87 return returnValue;
86 } 88 }
87 89
88 /** 90 /**
89 * 服务提供者事务方法处理. 91 * 服务提供者事务方法处理.
90 - * @param compensableMethodContext 92 + * @param methodContext
91 * @throws Throwable 93 * @throws Throwable
92 */ 94 */
93 - private Object providerMethodProceed(MethodContext compensableMethodContext) throws Throwable {  
94 - TransactionContext transactionContext = compensableMethodContext.getTransactionContext(); 95 + private Object providerMethodProceed(MethodContext methodContext) throws Throwable {
  96 + TransactionContext transactionContext = methodContext.getTransactionContext();
  97 + boolean asyncConfirm = methodContext.isAsyncConfirm();
  98 + boolean asyncCancel = methodContext.isAsyncCancel();
95 99
96 - LOG.debug("==>providerMethodProceed transactionStatus:{}", TransactionStatus.valueOf(transactionContext.getStatus()).toString()); 100 + LOG.debug("==>providerMethodProceed transactionStatus:{}",
  101 + TransactionStatus.valueOf(transactionContext.getStatus()).toString());
97 102
98 switch (TransactionStatus.valueOf(transactionContext.getStatus())) { 103 switch (TransactionStatus.valueOf(transactionContext.getStatus())) {
99 case TRYING: 104 case TRYING:
@@ -101,15 +106,15 @@ public class CompensableTransactionInterceptor { @@ -101,15 +106,15 @@ public class CompensableTransactionInterceptor {
101 // 基于全局事务ID扩展创建新的分支事务,并存于当前线程的事务局部变量中. 106 // 基于全局事务ID扩展创建新的分支事务,并存于当前线程的事务局部变量中.
102 transactionConfigurator.getTransactionManager().propagationNewBegin(transactionContext); 107 transactionConfigurator.getTransactionManager().propagationNewBegin(transactionContext);
103 LOG.debug("==>providerMethodProceed try end"); 108 LOG.debug("==>providerMethodProceed try end");
104 - return compensableMethodContext.proceed(); 109 + return methodContext.proceed();
105 case CONFIRMING: 110 case CONFIRMING:
106 try { 111 try {
107 LOG.debug("==>providerMethodProceed confirm begin"); 112 LOG.debug("==>providerMethodProceed confirm begin");
108 // 找出存在的事务并处理. 113 // 找出存在的事务并处理.
109 transactionConfigurator.getTransactionManager().propagationExistBegin(transactionContext); 114 transactionConfigurator.getTransactionManager().propagationExistBegin(transactionContext);
110 - transactionConfigurator.getTransactionManager().commit(); // 提交 115 + transactionConfigurator.getTransactionManager().commit(asyncConfirm); // 提交
111 LOG.debug("==>providerMethodProceed confirm end"); 116 LOG.debug("==>providerMethodProceed confirm end");
112 - } catch (NoExistedTransactionException excepton) { 117 + } catch (NoExistedTransactionException exception) {
113 //the transaction has been commit,ignore it. 118 //the transaction has been commit,ignore it.
114 } 119 }
115 break; 120 break;
@@ -117,7 +122,7 @@ public class CompensableTransactionInterceptor { @@ -117,7 +122,7 @@ public class CompensableTransactionInterceptor {
117 try { 122 try {
118 LOG.debug("==>providerMethodProceed cancel begin"); 123 LOG.debug("==>providerMethodProceed cancel begin");
119 transactionConfigurator.getTransactionManager().propagationExistBegin(transactionContext); 124 transactionConfigurator.getTransactionManager().propagationExistBegin(transactionContext);
120 - transactionConfigurator.getTransactionManager().rollback(); // 回滚 125 + transactionConfigurator.getTransactionManager().rollback(asyncCancel); // 回滚
121 LOG.debug("==>providerMethodProceed cancel end"); 126 LOG.debug("==>providerMethodProceed cancel end");
122 } catch (NoExistedTransactionException exception) { 127 } catch (NoExistedTransactionException exception) {
123 //the transaction has been rollback,ignore it. 128 //the transaction has been rollback,ignore it.
@@ -125,7 +130,7 @@ public class CompensableTransactionInterceptor { @@ -125,7 +130,7 @@ public class CompensableTransactionInterceptor {
125 break; 130 break;
126 } 131 }
127 132
128 - Method method = compensableMethodContext.getMethod(); 133 + Method method = methodContext.getMethod();
129 return ReflectionUtils.getNullValue(method.getReturnType()); 134 return ReflectionUtils.getNullValue(method.getReturnType());
130 } 135 }
131 136
tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.java
@@ -67,7 +67,7 @@ public class ResourceCoordinatorInterceptor { @@ -67,7 +67,7 @@ public class ResourceCoordinatorInterceptor {
67 } 67 }
68 68
69 LOG.debug("==>pjp.proceed(pjp.getArgs())"); 69 LOG.debug("==>pjp.proceed(pjp.getArgs())");
70 - return pjp.proceed(pjp.getArgs()); 70 + return methodContext.proceedWithInArgs();
71 } 71 }
72 72
73 /** 73 /**
tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/interceptor/invoke/MethodContext.java
@@ -118,6 +118,14 @@ public class MethodContext { @@ -118,6 +118,14 @@ public class MethodContext {
118 } 118 }
119 119
120 /** 120 /**
  121 + * 是否异步confirm。
  122 + * @return
  123 + */
  124 + public boolean isAsyncConfirm() {
  125 + return this.compensable.asyncConfirm();
  126 + }
  127 +
  128 + /**
121 * 获取cancel方法名。 129 * 获取cancel方法名。
122 * @return 130 * @return
123 */ 131 */
@@ -126,7 +134,15 @@ public class MethodContext { @@ -126,7 +134,15 @@ public class MethodContext {
126 } 134 }
127 135
128 /** 136 /**
129 - * 执行方法。 137 + * 是否异步cancel。
  138 + * @return
  139 + */
  140 + public boolean isAsyncCancel() {
  141 + return this.compensable.asyncCancel();
  142 + }
  143 +
  144 + /**
  145 + * 执行方法(切入点定义的是标注)。
130 * @return 146 * @return
131 * @throws Throwable 147 * @throws Throwable
132 */ 148 */
@@ -134,5 +150,14 @@ public class MethodContext { @@ -134,5 +150,14 @@ public class MethodContext {
134 return this.proceedingJoinPoint.proceed(); 150 return this.proceedingJoinPoint.proceed();
135 } 151 }
136 152
  153 + /**
  154 + * 执行方法(切入点定义的是方法签名)
  155 + * @return
  156 + * @throws Throwable
  157 + */
  158 + public Object proceedWithInArgs() throws Throwable {
  159 + return this.proceedingJoinPoint.proceed(this.getProceedingJoinPoint().getArgs());
  160 + }
  161 +
137 162
138 } 163 }
tcc-transaction-core/src/main/java/org/mengyun/tcctransaction/recover/RecoverConfig.java
@@ -22,4 +22,23 @@ public interface RecoverConfig { @@ -22,4 +22,23 @@ public interface RecoverConfig {
22 * @return 22 * @return
23 */ 23 */
24 String getCronExpression(); 24 String getCronExpression();
  25 +
  26 + /**
  27 + * 获取线程池中核心线程数的最大值.
  28 + * @return
  29 + */
  30 + int getAsyncTerminateThreadCorePoolSize();
  31 +
  32 + /**
  33 + * 获取线程池中能拥有最多线程数。
  34 + * @return
  35 + */
  36 + int getAsyncTerminateThreadMaxPoolSize();
  37 +
  38 + /**
  39 + * 获取用于缓存任务的阻塞队列。
  40 + * @return
  41 + */
  42 + int getAsyncTerminateThreadWorkQueueSize();
  43 +
25 } 44 }
tcc-transaction-core/target/classes/org/mengyun/tcctransaction/TransactionManager.class
No preview for this file type
tcc-transaction-core/target/classes/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor$1.class
No preview for this file type
tcc-transaction-core/target/classes/org/mengyun/tcctransaction/interceptor/CompensableTransactionInterceptor.class
No preview for this file type
tcc-transaction-core/target/classes/org/mengyun/tcctransaction/interceptor/ResourceCoordinatorInterceptor.class
No preview for this file type
tcc-transaction-core/target/classes/org/mengyun/tcctransaction/recover/RecoverConfig.class
No preview for this file type
tcc-transaction-spring/src/main/java/org/mengyun/tcctransaction/spring/recover/DefaultRecoverConfig.java
@@ -21,6 +21,28 @@ public class DefaultRecoverConfig implements RecoverConfig { @@ -21,6 +21,28 @@ public class DefaultRecoverConfig implements RecoverConfig {
21 /** 恢复Job触发间隔配置,默认是(每分钟) */ 21 /** 恢复Job触发间隔配置,默认是(每分钟) */
22 private String cronExpression = "0 */1 * * * ?"; 22 private String cronExpression = "0 */1 * * * ?";
23 23
  24 + /** 线程池中核心线程数的最大值 */
  25 + private int asyncTerminateThreadCorePoolSize = 512;
  26 + /** 线程池中能拥有最多线程数 */
  27 + private int asyncTerminateThreadMaxPoolSize = 1024;
  28 + /** 用于缓存任务的阻塞队列 */
  29 + private int asyncTerminateThreadWorkQueueSize = 512;
  30 +
  31 + @Override
  32 + public int getAsyncTerminateThreadCorePoolSize() {
  33 + return asyncTerminateThreadCorePoolSize;
  34 + }
  35 +
  36 + @Override
  37 + public int getAsyncTerminateThreadMaxPoolSize() {
  38 + return asyncTerminateThreadMaxPoolSize;
  39 + }
  40 +
  41 + @Override
  42 + public int getAsyncTerminateThreadWorkQueueSize() {
  43 + return asyncTerminateThreadWorkQueueSize;
  44 + }
  45 +
24 @Override 46 @Override
25 public int getMaxRetryCount() { 47 public int getMaxRetryCount() {
26 return maxRetryCount; 48 return maxRetryCount;
tcc-transaction-spring/src/main/java/org/mengyun/tcctransaction/spring/support/TccTransactionConfigurator.java
@@ -9,6 +9,8 @@ import org.mengyun.tcctransaction.support.TransactionConfigurator; @@ -9,6 +9,8 @@ import org.mengyun.tcctransaction.support.TransactionConfigurator;
9 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Autowired;
10 10
11 import javax.annotation.PostConstruct; 11 import javax.annotation.PostConstruct;
  12 +import java.util.concurrent.*;
  13 +import java.util.concurrent.atomic.AtomicInteger;
12 14
13 /** 15 /**
14 * Created by changmingxie on 11/11/15. 16 * Created by changmingxie on 11/11/15.
@@ -32,15 +34,16 @@ public class TccTransactionConfigurator implements TransactionConfigurator { @@ -32,15 +34,16 @@ public class TccTransactionConfigurator implements TransactionConfigurator {
32 return recoverConfig; 34 return recoverConfig;
33 } 35 }
34 36
35 - /**  
36 - * 根据事务配置器创建事务管理器.  
37 - */ 37 + /** 事务管理器 */
38 private TransactionManager transactionManager = new TransactionManager(); 38 private TransactionManager transactionManager = new TransactionManager();
39 @Override 39 @Override
40 public TransactionManager getTransactionManager() { 40 public TransactionManager getTransactionManager() {
41 return transactionManager; 41 return transactionManager;
42 } 42 }
43 43
  44 + /** 线程池配置 */
  45 + private static volatile ExecutorService executorService;
  46 +
44 @PostConstruct 47 @PostConstruct
45 public void init() { 48 public void init() {
46 // 属性注入后调用 49 // 属性注入后调用
@@ -52,10 +55,59 @@ public class TccTransactionConfigurator implements TransactionConfigurator { @@ -52,10 +55,59 @@ public class TccTransactionConfigurator implements TransactionConfigurator {
52 recoverConfig.getRecoverDuration() 55 recoverConfig.getRecoverDuration()
53 ); 56 );
54 } 57 }
  58 +
55 // 2、事务配置器配置事务repo 59 // 2、事务配置器配置事务repo
56 transactionManager.setTransactionRepository(transactionRepository); 60 transactionManager.setTransactionRepository(transactionRepository);
57 61
58 - // TODO:3、executeService配置 62 + // 3、线程池配置
  63 + if (executorService == null) {
  64 + executorService = new ThreadPoolExecutor(
  65 + recoverConfig.getAsyncTerminateThreadCorePoolSize(), // 核心线程数
  66 + recoverConfig.getAsyncTerminateThreadMaxPoolSize(), // 最大线程数
  67 + 5L, // 最大空闲时间
  68 + TimeUnit.SECONDS, // 时间单位(秒)
  69 + new ArrayBlockingQueue<Runnable>( // 缓存任务的阻塞队列
  70 + recoverConfig.getAsyncTerminateThreadWorkQueueSize()),
  71 + new ThreadFactory() { // 创建线程的工厂
  72 + final AtomicInteger poolNumber = new AtomicInteger(1);
  73 + final ThreadGroup group;
  74 + final AtomicInteger threadNumber = new AtomicInteger(1);
  75 + final String namePrefix;
  76 +
  77 + {
  78 + SecurityManager securityManager = System.getSecurityManager();
  79 + if (securityManager == null) {
  80 + this.group = Thread.currentThread().getThreadGroup();
  81 + } else {
  82 + this.group = securityManager.getThreadGroup();
  83 + }
  84 + this.namePrefix = "tcc-async-terminate-pool-" + poolNumber.getAndIncrement() + "-thread-";
  85 + }
  86 +
  87 + @Override
  88 + public Thread newThread(Runnable r) {
  89 + Thread thread = new Thread(
  90 + this.group,
  91 + r,
  92 + this.namePrefix + this.threadNumber.getAndIncrement(),
  93 + 0L
  94 + );
  95 + if (thread.isDaemon()) {
  96 + thread.setDaemon(false);
  97 + }
  98 +
  99 + if (thread.getPriority() != 5) {
  100 + thread.setPriority(5);
  101 + }
  102 +
  103 + return thread;
  104 + }
  105 + },
  106 + new ThreadPoolExecutor.CallerRunsPolicy() // 线程池满了且任务队列也满了,由向线程池提交任务的线程来执行该任务
  107 + );
  108 + }
  109 + transactionManager.setExecutorService(executorService);
  110 +
59 } 111 }
60 112
61 113
tcc-transaction-spring/target/classes/org/mengyun/tcctransaction/spring/recover/DefaultRecoverConfig.class
No preview for this file type
tcc-transaction-spring/target/classes/org/mengyun/tcctransaction/spring/support/TccTransactionConfigurator.class
No preview for this file type