使用lambda表达式优雅你的事务代码

我们在实现业务逻辑时,经常会有这种需求:
1、在当前事务A中开启新事务B,事务B中发生异常不可以回滚A,事务B成功执行后返回事务B的返回值;
2、在当前事务A中开启新事务B,事务B中发生异常要求回滚A,事务B成功执行后返回事务B的返回值;
3、在当前事务A中开启新事务B,事务B中发生异常不可以回滚A,事务B成功执行后不需要返回;
4、在当前事务A中开启新事务B,事务B中发生异常要求回滚A,事务B成功执行后不需要返回;
5、注册后置事务B,即当前事务A成功提交后才会执行事务B,事务B异常的话不抛出,只打印异常日志;
6、注册后置事务B,即当前事务A异常时执行事务B,事务B异常的话不抛出,只打印异常日志;

【使用lambda表达式优雅你的事务代码】
一、配置事务模版



二、定义接口
/** * @author zhaojiatao * @date 2019-07-14 */ public interface ICommonTransactionService {/** * 开启一个新事务来执行函数,有返回值; 与外部事务互相隔离,发生异常只回滚本事务,不会互相影响 * @param action * @param * @urn */ T newTransactionExecuteAndReturnWithOutThrowable(Supplier action); /** * 开启一个新事务来执行函数,有返回值; 内部事务发生异常时会向外抛出异常,内部事务和外部事务均回滚 * @param action * @param * @urn */ T newTransactionExecuteAndReturnThrowable(Supplier action) throws Exception; /** * 开启一个新事务来执行函数,无返回值; 与外部事务互相隔离,发生异常只回滚本事务,不会互相影响 * @param f */ void newTransactionRunVoidWithOutThrowable(Runnable f); /** * 开启一个新事务来执行函数,无返回值; 内部事务发生异常时会向外抛出异常,内部事务和外部事务均回滚 * @param f */ void newTransactionRunVoidThrowable(Runnable f) throws Exception; /** * 如果当前存在事务,则等当前事务提交后,回头来开启一个新事务执行,如果内部捕捉异常,不往外抛出; 如果外部事务提交前外部事物异常,则此函数不会被执行 * https://docs.spring.io/spring/docs/1.2.7/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationAdapter.html * @param f */ void registerTransactionAfterCommitNoThrowable(Runnable f); /** * 当前事务提交或者回滚后执行 Invoked after transaction commit/rollback * https://docs.spring.io/spring/docs/1.2.7/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationAdapter.html * @param f */ void registerTransactionAfterRollBackNoThrowable(Runnable f); }



三、接口实现
/** * @author zhaojiatao * @date 2019-07-14 */@Slf4j @Service("commonTransactionService") public class CommonTransactionServiceImplimplements ICommonTransactionService {@Autowired @Qualifier("transactionTemplateNew") TransactionTemplate transactionTemplateNew; @Override public T newTransactionExecuteAndReturnWithOutThrowable(Supplier action) { //执行带有返回值的事务管理 return transactionTemplateNew.execute(transactionStatus-> { try { return action.get(); } catch (Exception e) { log.error("newTransactionExecuteAndReturnNoThrowable发生异常",e); //回滚 transactionStatus.setRollbackOnly(); return null; } }); }@Override public T newTransactionExecuteAndReturnThrowable(Supplier action) { //执行带有返回值的事务管理 return transactionTemplateNew.execute(transactionStatus-> { try { return action.get(); } catch (Exception e) { log.error("newTransactionExecuteAndReturnNoThrowable发生异常",e); //回滚 transactionStatus.setRollbackOnly(); throw e; } }); }@Override public void newTransactionRunVoidWithOutThrowable(Runnable f) { //执行无返回值的事务管理 transactionTemplateNew.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { try { //业务代码 f.run(); } catch (Exception e){ log.error("newTransactionRunVoidNoThrowable发生异常",e); //回滚 transactionStatus.setRollbackOnly(); }} }); }@Override public void newTransactionRunVoidThrowable(Runnable f) { //执行无返回值的事务管理 transactionTemplateNew.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { try { //业务代码 f.run(); } catch (Exception e){ log.error("newTransactionRunVoidNoThrowable发生异常",e); //回滚 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("执行事务回滚后置事务,status={}",status); f.run(); } }); } else { f.run(); } }catch (Exception e){ log.error("当前事务回滚后置事务发生异常",e); } }}



四、调用
@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]+""); //只回滚内部事务,不回滚外部事务 System.out.println(1/0); } ); //4、在外部事务提交后执行的后置新事务insert数据 commonTransactionService.registerTransactionAfterCommitNoThrowable( ()->{ OrderDO orderDO=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("353353"); 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); } ); //注意验证这个异常是无法回滚commonTransactionService.newTransactionRun的 //注意验证这个异常会导致commonTransactionService.registerTransactionAfterCommitNoThrowable无法执行,因为事务没有提交 //System.out.println(1/0); System.out.println(1); }


转载于:https://www.cnblogs.com/zhaojiatao/p/11238430.html

    推荐阅读