diff --git a/pom.xml b/pom.xml index d72e3b7b4d7318e369616773c39b6dbed5a6eff9..f7da41e8ae9027fee06c2392d9c68711907854db 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,7 @@ 1.8.0 2.7.8 3.13.2.Final - 1.3.0 + 1.4.0 1.1.8 4.1.16 diff --git a/src/main/java/io/jboot/support/seata/JbootSeataManager.java b/src/main/java/io/jboot/support/seata/JbootSeataManager.java index 119b6bfa23ca715fc193c5d2cb2280c017e9cf93..c3ed560ca99d29d9b44d863a447f9e5382d5fe0f 100644 --- a/src/main/java/io/jboot/support/seata/JbootSeataManager.java +++ b/src/main/java/io/jboot/support/seata/JbootSeataManager.java @@ -45,7 +45,7 @@ public class JbootSeataManager { private boolean enable = false; private TransactionalTemplate transactionalTemplate; - private GlobalLockTemplate globalLockTemplate; + private GlobalLockTemplate globalLockTemplate; private SeataGlobalTransactionManager transactionManager; @@ -69,7 +69,7 @@ public class JbootSeataManager { transactionManager.init(); this.transactionalTemplate = new TransactionalTemplate(); - this.globalLockTemplate = new GlobalLockTemplate<>(); + this.globalLockTemplate = new GlobalLockTemplate(); this.enable = true; } @@ -118,11 +118,11 @@ public class JbootSeataManager { this.transactionalTemplate = transactionalTemplate; } - public GlobalLockTemplate getGlobalLockTemplate() { + public GlobalLockTemplate getGlobalLockTemplate() { return globalLockTemplate; } - public void setGlobalLockTemplate(GlobalLockTemplate globalLockTemplate) { + public void setGlobalLockTemplate(GlobalLockTemplate globalLockTemplate) { this.globalLockTemplate = globalLockTemplate; } diff --git a/src/main/java/io/jboot/support/seata/annotation/SeataGlobalLock.java b/src/main/java/io/jboot/support/seata/annotation/SeataGlobalLock.java index 9a96b2e1858112087a05832ec9e4f35f208ceff5..fa8652cd61892545a65077ab294565f92407938f 100644 --- a/src/main/java/io/jboot/support/seata/annotation/SeataGlobalLock.java +++ b/src/main/java/io/jboot/support/seata/annotation/SeataGlobalLock.java @@ -34,4 +34,9 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) @Inherited public @interface SeataGlobalLock { + + int lockRetryInternal() default 0; + + int lockRetryTimes() default -1; + } diff --git a/src/main/java/io/jboot/support/seata/annotation/SeataGlobalTransactional.java b/src/main/java/io/jboot/support/seata/annotation/SeataGlobalTransactional.java index fc21d01f8b6884769d7f9fffe3ede202ebaf3546..27433fea6ee6bfff6bb2d035a47233420b59f25d 100644 --- a/src/main/java/io/jboot/support/seata/annotation/SeataGlobalTransactional.java +++ b/src/main/java/io/jboot/support/seata/annotation/SeataGlobalTransactional.java @@ -33,7 +33,7 @@ public @interface SeataGlobalTransactional { * * @return timeoutMills in MILLISECONDS. */ - int timeoutMills() default TransactionInfo.DEFAULT_TIME_OUT; + int timeoutMills() default 60000; /** * Given name of the global transaction instance. diff --git a/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalInterceptorBuilder.java b/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalInterceptorBuilder.java index 738b26464b5f160a8afc46b3ec671879f1cbeb86..cee772cf4ceb39f467ef209af77cd81c28964200 100644 --- a/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalInterceptorBuilder.java +++ b/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalInterceptorBuilder.java @@ -37,7 +37,7 @@ public class SeataGlobalInterceptorBuilder implements InterceptorBuilder { final SeataGlobalLock globalLockAnno = method.getAnnotation(SeataGlobalLock.class); if (globalTrxAnno != null || globalLockAnno != null){ - interceptors.add(SeataGlobalTransactionalInterceptor.class); + interceptors.add(SeataGlobalTransactionalInterceptor.class, 0); } } diff --git a/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalTransactionalInterceptor.java b/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalTransactionalInterceptor.java index de070e467732120ccbec5f4615c673430cdea890..274f1a0f1ce3088b97a5e7d23cd3c8aab85d7160 100644 --- a/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalTransactionalInterceptor.java +++ b/src/main/java/io/jboot/support/seata/interceptor/SeataGlobalTransactionalInterceptor.java @@ -20,6 +20,8 @@ import com.jfinal.aop.Invocation; import io.jboot.support.seata.JbootSeataManager; import io.jboot.support.seata.annotation.SeataGlobalLock; import io.jboot.support.seata.annotation.SeataGlobalTransactional; +import io.seata.core.model.GlobalLockConfig; +import io.seata.rm.GlobalLockExecutor; import java.lang.reflect.Method; @@ -48,7 +50,7 @@ public class SeataGlobalTransactionalInterceptor implements Interceptor { if (globalTrxAnno != null) { handleGlobalTransaction(inv, globalTrxAnno); } else if (globalLockAnno != null) { - handleGlobalLock(inv); + handleGlobalLock(inv,globalLockAnno); } else { inv.invoke(); } @@ -59,17 +61,20 @@ public class SeataGlobalTransactionalInterceptor implements Interceptor { } - private void handleGlobalLock(final Invocation inv) throws Exception { - JbootSeataManager.me().getGlobalLockTemplate().execute(() -> { - try { + private void handleGlobalLock(final Invocation inv, final SeataGlobalLock globalLockAnno) throws Throwable { + JbootSeataManager.me().getGlobalLockTemplate().execute(new GlobalLockExecutor() { + @Override + public Object execute() throws Throwable { inv.invoke(); return inv.getReturnValue(); - } catch (Throwable e) { - if (e instanceof Exception) { - throw (Exception)e; - } else { - throw new RuntimeException(e); - } + } + + @Override + public GlobalLockConfig getGlobalLockConfig() { + GlobalLockConfig config = new GlobalLockConfig(); + config.setLockRetryInternal(globalLockAnno.lockRetryInternal()); + config.setLockRetryTimes(globalLockAnno.lockRetryTimes()); + return config; } }); } diff --git a/src/main/java/io/jboot/support/seata/tcc/TccActionInterceptor.java b/src/main/java/io/jboot/support/seata/tcc/TccActionInterceptor.java index 1f0d35aab3a61ed8500abc934b4f970b50541725..e22bddc1d25579a24fd99e77255c457d2da61648 100644 --- a/src/main/java/io/jboot/support/seata/tcc/TccActionInterceptor.java +++ b/src/main/java/io/jboot/support/seata/tcc/TccActionInterceptor.java @@ -60,17 +60,18 @@ public class TccActionInterceptor implements Interceptor { //save the xid String xid = RootContext.getXID(); //clear the context - String previousBranchType = RootContext.getBranchType(); - RootContext.bindBranchType(BranchType.TCC); + BranchType previousBranchType = RootContext.getBranchType(); + if (BranchType.TCC != previousBranchType) { + RootContext.bindBranchType(BranchType.TCC); + } try { Object[] methodArgs = inv.getArgs(); //Handler the TCC Aspect actionInterceptorHandler.proceed(method, methodArgs, xid, businessAction, inv); } finally { - RootContext.unbindBranchType(); - //restore the TCC branchType if exists - if (StringUtils.equals(BranchType.TCC.name(), previousBranchType)) { - RootContext.bindBranchType(BranchType.TCC); + //if not TCC, unbind branchType + if (BranchType.TCC != previousBranchType) { + RootContext.unbindBranchType(); } } } else { diff --git a/src/test/java/io/jboot/test/seata/account/AccountServiceProvider.java b/src/test/java/io/jboot/test/seata/account/AccountServiceProvider.java index 720af52eb10967acca3590cca43603f3a837f4df..6e595dd20d0df67ef4fa04ed8a0e6903ba895098 100644 --- a/src/test/java/io/jboot/test/seata/account/AccountServiceProvider.java +++ b/src/test/java/io/jboot/test/seata/account/AccountServiceProvider.java @@ -41,7 +41,7 @@ public class AccountServiceProvider extends JbootServiceBase implements public boolean update(String account, Integer money) { Account account1 = dao.findFirst("select * from seata_account where account = ? ", account); account1.set("store", account1.getInt("store") - money); - account1.set("money", account1.getInt("money") - money); + account1.set("money", account1.getInt("money") + money); return account1.saveOrUpdate(); } } diff --git a/src/test/java/io/jboot/test/seata/business/BusinessServiceProvider.java b/src/test/java/io/jboot/test/seata/business/BusinessServiceProvider.java index 690c6660988db346b2f018a56dd14333f1478d1e..43db9dfaf970f7787b1fef51156b1d9220835a70 100644 --- a/src/test/java/io/jboot/test/seata/business/BusinessServiceProvider.java +++ b/src/test/java/io/jboot/test/seata/business/BusinessServiceProvider.java @@ -1,6 +1,7 @@ package io.jboot.test.seata.business; +import com.jfinal.aop.Inject; import io.jboot.components.rpc.annotation.RPCInject; import io.jboot.service.JbootServiceBase; import io.jboot.support.seata.annotation.SeataGlobalTransactional; @@ -10,15 +11,14 @@ import io.jboot.test.seata.stock.IStockService; public class BusinessServiceProvider extends JbootServiceBase { - @RPCInject + @Inject private IAccountService accountService; - @RPCInject + @Inject private IStockService stockService; - @SeataGlobalTransactional(timeoutMills = 300000, name = "Dubbo_Seata_Business_Transactional") public boolean deposit(Integer accountId) { - accountService.deposit(accountId, 1000); - stockService.deposit(accountId, 2000); + accountService.deposit(accountId, 100); + stockService.deposit(accountId, 200); return true; } diff --git a/src/test/java/io/jboot/test/seata/interceptor/ExceptionInterceptor.java b/src/test/java/io/jboot/test/seata/interceptor/ExceptionInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..c594ee88debdd22e92e2ebf160fb0197316e79a3 --- /dev/null +++ b/src/test/java/io/jboot/test/seata/interceptor/ExceptionInterceptor.java @@ -0,0 +1,24 @@ +package io.jboot.test.seata.interceptor; + +import com.jfinal.aop.Interceptor; +import com.jfinal.aop.Invocation; +import com.jfinal.kit.StrKit; +import io.jboot.web.controller.JbootController; + +/** + * @program: jboot + * @description: ${description} + * @author: zxn + * @create: 2021-01-12 23:45 + **/ +public class ExceptionInterceptor implements Interceptor { + + @Override + public void intercept(Invocation invocation) { + invocation.invoke(); + JbootController jbootController = (JbootController) invocation.getController(); + if (StrKit.notBlank(jbootController.getPara("flag"))){ + int i = 1/0; + } + } +} diff --git a/src/test/java/io/jboot/test/seata/starter/AccountApplicaiton.java b/src/test/java/io/jboot/test/seata/starter/AccountApplicaiton.java index a5ff01e51c8a887170739c114eb1c371ae38ab4b..db3d1034d7fdd440c5b375943e774cd9f3f4ff52 100644 --- a/src/test/java/io/jboot/test/seata/starter/AccountApplicaiton.java +++ b/src/test/java/io/jboot/test/seata/starter/AccountApplicaiton.java @@ -19,13 +19,13 @@ public class AccountApplicaiton { JbootApplication.setBootArg("jboot.rpc.autoExportEnable", true); JbootApplication.setBootArg("jboot.seata.enable", true); - JbootApplication.setBootArg("jboot.seata.failureHandler", "com.alibaba.io.seata.tm.api.DefaultFailureHandlerImpl"); + JbootApplication.setBootArg("jboot.seata.failureHandler", "io.seata.tm.api.DefaultFailureHandlerImpl"); JbootApplication.setBootArg("jboot.seata.applicationId", "Dubbo_Seata_Account_Service"); JbootApplication.setBootArg("jboot.seata.txServiceGroup", "dubbo_seata_tx_group"); JbootApplication.setBootArg("jboot.datasource.type", "mysql"); - JbootApplication.setBootArg("jboot.datasource.url", "jdbc:mysql://192.168.0.100:3306/mini?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull"); + JbootApplication.setBootArg("jboot.datasource.url", "jdbc:mysql://127.0.0.1:3306/mini?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull"); JbootApplication.setBootArg("jboot.datasource.user", "root"); - JbootApplication.setBootArg("jboot.datasource.password", "123456"); + JbootApplication.setBootArg("jboot.datasource.password", "zhang123"); JbootApplication.setBootArg("jboot.model.unscanPackage", "*"); JbootApplication.setBootArg("jboot.model.scanPackage", "io.jboot.test.seata.commons"); diff --git a/src/test/java/io/jboot/test/seata/starter/StockApplication.java b/src/test/java/io/jboot/test/seata/starter/StockApplication.java index e54a8ec096a30a66d9525e71a322f4040123cfbd..788efbc7288fc9d82fb6a19de6543f2b7562255c 100644 --- a/src/test/java/io/jboot/test/seata/starter/StockApplication.java +++ b/src/test/java/io/jboot/test/seata/starter/StockApplication.java @@ -18,14 +18,14 @@ public class StockApplication { JbootApplication.setBootArg("jboot.rpc.autoExportEnable", true); JbootApplication.setBootArg("jboot.rpc.filter", "seata"); JbootApplication.setBootArg("jboot.seata.enable", true); - JbootApplication.setBootArg("jboot.seata.failureHandler", "com.alibaba.io.seata.tm.api.DefaultFailureHandlerImpl"); + JbootApplication.setBootArg("jboot.seata.failureHandler", "io.seata.tm.api.DefaultFailureHandlerImpl"); JbootApplication.setBootArg("jboot.seata.applicationId", "Dubbo_Seata_Stock_Service"); JbootApplication.setBootArg("jboot.seata.txServiceGroup", "dubbo_seata_tx_group"); JbootApplication.setBootArg("jboot.datasource.type", "mysql"); - JbootApplication.setBootArg("jboot.datasource.url", "jdbc:mysql://192.168.0.100:3306/mini?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull"); + JbootApplication.setBootArg("jboot.datasource.url", "jdbc:mysql://127.0.0.1:3306/mini?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull"); JbootApplication.setBootArg("jboot.datasource.user", "root"); - JbootApplication.setBootArg("jboot.datasource.password", "123456"); + JbootApplication.setBootArg("jboot.datasource.password", "zhang123"); JbootApplication.setBootArg("jboot.model.unscanPackage", "*"); JbootApplication.setBootArg("jboot.model.scanPackage", "io.jboot.test.seata.commons"); diff --git a/src/test/java/io/jboot/test/seata/starter/WebApplication.java b/src/test/java/io/jboot/test/seata/starter/WebApplication.java index 970bfc0af48a47127310a054c75e32e2b9c621a9..d8642529df66c94b52d6d3bc6542e1ca5e396a0d 100644 --- a/src/test/java/io/jboot/test/seata/starter/WebApplication.java +++ b/src/test/java/io/jboot/test/seata/starter/WebApplication.java @@ -1,9 +1,11 @@ package io.jboot.test.seata.starter; +import com.jfinal.aop.Before; import com.jfinal.aop.Inject; import io.jboot.app.JbootApplication; import io.jboot.support.seata.annotation.SeataGlobalTransactional; import io.jboot.test.seata.business.BusinessServiceProvider; +import io.jboot.test.seata.interceptor.ExceptionInterceptor; import io.jboot.test.seata.service.TccActionOneService; import io.jboot.web.controller.JbootController; import io.jboot.web.controller.annotation.RequestMapping; @@ -45,6 +47,8 @@ public class WebApplication extends JbootController { @Inject private TccActionOneService tccActionOneService; + @Before(ExceptionInterceptor.class) + @SeataGlobalTransactional(timeoutMills = 300000, name = "Dubbo_Seata_Business_Transactional") public void index() { System.out.println("WebApplication.index()"); @@ -58,7 +62,7 @@ public class WebApplication extends JbootController { tccActionOneService.prepare(null, "Hobbit", 10, getParaToBoolean("flag")); /*if (getParaToBoolean("flag")) { throw new RuntimeException("you have fail"); - }*/ + }*/ renderJson("you are sucess"); } diff --git a/src/test/java/io/jboot/test/seata/stock/StockServiceProvider.java b/src/test/java/io/jboot/test/seata/stock/StockServiceProvider.java index 6561c11360f00704c79e00a90b2cd6a9bf894939..3cd874db7455901ea4a26035ede204ef0c55f014 100644 --- a/src/test/java/io/jboot/test/seata/stock/StockServiceProvider.java +++ b/src/test/java/io/jboot/test/seata/stock/StockServiceProvider.java @@ -1,11 +1,13 @@ package io.jboot.test.seata.stock; +import io.jboot.aop.annotation.Bean; import io.jboot.components.rpc.annotation.RPCBean; import io.jboot.service.JbootServiceBase; import io.jboot.test.seata.commons.Stock; @RPCBean +@Bean public class StockServiceProvider extends JbootServiceBase implements IStockService { private static Stock dao = new Stock().dao();