使用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 publicT newTransactionExecuteAndReturnWithOutThrowable(Supplier action) { //执行带有返回值
四、调用
@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
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)