When we implement business logic, often have this need:
1, open in the current transaction B A new transaction, transaction rollback not abnormality occurs in B A, B returns the transaction after transaction successful execution return value B;
2, open in the current transaction B A new transaction, transaction rollback in claim abnormality occurs B A, B returns the transaction after transaction successful execution return value B;
3, opened in the current transaction B A new transaction, transaction rollback not abnormality occurs in B A, B need not be returned after the successful execution of the transaction;
4, the opening in the current transaction A new transaction B, B transaction rollback abnormality occurs in claim A, B need not be returned after the successful execution of the transaction;
5, registered post transaction B, B will execute a transaction that is after the current transaction A successful submission, transaction B does not throw an exception, then print only exception log;
6, registered post transaction B, that is, the current transaction A transaction B when abnormal execution, transaction B does not throw an exception, then print only exception log;
First, configure the template affairs
<-! Affairs template 1. REQUIRES_NEW will mark a new turn affairs, external affairs will be aberrant outer hall Affairs, submitted does not roll back the internal affairs of internal affairs 2. REQUIRES_NEW sign of abnormality, internal rolls back the transaction, external affairs rolled back -> <the bean ID = "transactionTemplateNew" class = "org.springframework.transaction.support.TransactionTemplate"> <Property name = "the transactionManager"> <REF = the bean "the transactionManager" /> </ Property> < name = Property "propagationBehaviorName" value = "the PROPAGATION_REQUIRES_NEW" /> </ the bean>
Second, the definition of the interface
/ ** * @author zhaojiatao * @date 2019-07-14 * / public interface ICommonTransactionService { / ** * open a new transaction to execute the function, the return value; the external transaction isolation from each other, only the abnormal present transaction rollback , do not affect each * @param Action * @param <T> * @urn * / <T> T newTransactionExecuteAndReturnWithOutThrowable (Supplier <T> Action); / ** * open a new transaction to execute the function, the return value; internal transaction occurs when an exception is thrown outwardly abnormal, both internal affairs and external transaction rollback * @param Action * @param <T> * @urn * / <T> T newTransactionExecuteAndReturnThrowable (Supplier <T> Action) throws Exception; / ** * open a new transaction to execute the function returns no value; the external transaction isolation from each other, only the abnormal transaction rollback present, do not affect each * @param F * / void newTransactionRunVoidWithOutThrowable (the Runnable F); / ** * open a new transaction to execute the function returns no value; exception will be thrown out when the abnormality of the internal transaction occurs, external and internal transactions are rolled back transaction * @ param f * / void newTransactionRunVoidThrowable (Runnable f) throws exception; / ** * If the current transaction exists, the current transaction commits, etc., back to open a new transaction execution, if the internal catch the exception, not throw out; if external affairs before submitting an abnormal external things, this function will not be executed *https://docs.spring.io/spring/docs/1.2.7/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationAdapter.html * @param F * / void registerTransactionAfterCommitNoThrowable (the Runnable F); / ** * Invoked after the execution of the current transaction is committed or rolled back the commit transaction / rOLLBACK * https://docs.spring.io/spring/docs/1.2.7/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationAdapter.html * @ param F * / void registerTransactionAfterRollBackNoThrowable (the Runnable F); }
Third, the interface
/** * @author zhaojiatao * @date 2019-07-14 */ @Slf4j @Service("commonTransactionService") public class CommonTransactionServiceImpl implements ICommonTransactionService { @Autowired @Qualifier("transactionTemplateNew") TransactionTemplate transactionTemplateNew; @Override public <T> T newTransactionExecuteAndReturnWithOutThrowable(Supplier<T> action) { //执行带有返回值<Object>的事务管理 return transactionTemplateNew.execute(transactionStatus-> { the try { return action.get (); } the catch (Exception E) { log.error ( "newTransactionExecuteAndReturnNoThrowable abnormal" , E); // Rollback transactionStatus.setRollbackOnly (); return null ; } }); } @Override public <T> T newTransactionExecuteAndReturnThrowable (Supplier <T> Action) { // perform transaction management with a return value <Object> to returntransactionTemplateNew.execute (transactionStatus-> { the try { return action.get (); } the catch (Exception E) { log.error ( "newTransactionExecuteAndReturnNoThrowable abnormal" , E); // Rollback transactionStatus.setRollbackOnly (); the throw E; } }); } @Override public void newTransactionRunVoidWithOutThrowable (the Runnable F) { // perform transaction management None return value transactionTemplateNew.execute ( new new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { try { //业务代码 f.run(); } catch (Exception e){ log.error("newTransactionRunVoidNoThrowable发生异常",e); //回滚 transactionStatus.setRollbackOnly(); } } }); } @Override public voidnewTransactionRunVoidThrowable (the Runnable F) { // perform no return value transaction management transactionTemplateNew.execute ( new new TransactionCallbackWithoutResult () { @Override protected void doInTransactionWithoutResult (TransactionStatus TransactionStatus) { the try { // service code f.run (); } the catch (Exception E) { log.error ( "newTransactionRunVoidNoThrowable abnormal" , E); // rollback transactionStatus.setRollbackOnly (); throw e; } } }); } @Override public void registerTransactionAfterCommitNoThrowable(Runnable f) { try{ if (TransactionSynchronizationManager.isActualTransactionActive()) { TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCommit() { f.run(); } }); } else { f.run(); } }catch (Exception e){ log.error("执行后置事务发生异常",e); } } @Override public void registerTransactionAfterRollBackNoThrowable(Runnable f) { try{ if (TransactionSynchronizationManager.isActualTransactionActive()) { TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCompletion(int status) { log.error ( "post-execution transaction rollback transaction, Status = {}" , Status); f.run (); } }); } the else { f.run (); } } the catch (Exception E) { log .error ( "the transaction rollback transaction counter current abnormality" , E); } } }
Fourth, call
@Test @Transactional(rollbackFor = Exception.class) public void commonTransactionServiceTest() throws Exception { //1、newTransactionExecute 开启新事务 有返回值 String result=commonTransactionService.newTransactionExecuteAndReturnWithOutThrowable( ()->{ QueryObj queryObj = new QueryObj(); queryObj.setQuerydo(new OrderDO()); queryObj.addQueryParam(new QueryParam("id = #{id}", "347")); OrderDO orderDO = orderDAO.querySingle(queryObj); return JSON.toJSONString(orderDO); } ); log.info(result); //2、newTransactionRun 开启新事务 无返回值 commonTransactionService.newTransactionRunVoidWithOutThrowable( ()->{ QueryObj queryObj = new QueryObj(); queryObj.setQuerydo(new OrderDO()); queryObj.addQueryParam(new QueryParam("id = #{id}", "347")); OrderDO orderDO = orderDAO.querySingle(queryObj); log.info(JSON.toJSONString(orderDO)); } ); int[] ids=new int[]{0}; //3、在新事务中insert数据 commonTransactionService.newTransactionRunVoidWithOutThrowable( ()->{ OrderDO orderDO=new OrderDO(); orderDO.setId(350L); orderDO.setOrderCode("350350"); orderDO.setCustomerId(81L); orderDO.setBusinessModel (LoanOrderBusinessModelEnum.SELF_SECOND_CAR_ICBC_DIRECT.getCode ()); IDS [ 0] = orderDAO.create (orderDO); log.info (IDS [ 0] + "" ); // only internal transaction rollback, not external rollback transaction System.out.println (1/0 ); } ); // . 4, the rear insert new transaction data outside after performing the transaction commits commonTransactionService.registerTransactionAfterCommitNoThrowable ( () -> { orderDO orderDO = new new orderDO (); orderDO .setId ( 351l); orderDO.setOrderCode("351351"); orderDO.setCustomerId(81L); orderDO.setBusinessModel(LoanOrderBusinessModelEnum.SELF_SECOND_CAR_ICBC_DIRECT.getCode()); ids[0]=orderDAO.create(orderDO); log.info( ids[0]+""); } ); //5、在外部事务中insert数据 if(true){ OrderDO orderDO=new OrderDO(); orderDO.setId(352L); orderDO.setOrderCode("352352"); orderDO.setCustomerId(81L); orderDO.setBusinessModel(LoanOrderBusinessModelEnum.SELF_SECOND_CAR_ICBC_DIRECT.getCode()); ids[0]=orderDAO.create(orderDO); log.info( ids[0]+""); } //6、在新事务中插入数据并异常 commonTransactionService.newTransactionRunVoidThrowable( ()->{ OrderDO orderDO=new OrderDO(); orderDO.setId(353L); orderDO.setOrderCode ( "353 353" ); orderDO.setCustomerId ( 81L ); orderDO.setBusinessModel (LoanOrderBusinessModelEnum.SELF_SECOND_CAR_ICBC_DIRECT.getCode ()); IDS [ 0] = orderDAO.create (orderDO); log.info (IDS [ 0] + "" ); System.out.println ( 1/0 ); } ); // Note verify that this exception is not the rollback commonTransactionService.newTransactionRun // Note that this disorder can cause commonTransactionService.registerTransactionAfterCommitNoThrowable verification can not be performed because the transaction did not submit // System.out.println (1 / 0); System.out.println (. 1 ); }