• 使用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异常的话不抛出,只打印异常日志;


    一、配置事务模版

    <!--事务模版
        1.标志REQUIRES_NEW会新开启事务,外层事务异常外部事务会会馆,不会回滚内部事务的提交
        2.标志REQUIRES_NEW的内部事务的异常,内部事务会回滚,外部事务也会回滚-->
        <bean id="transactionTemplateNew" class="org.springframework.transaction.support.TransactionTemplate">
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
            <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>
        </bean>

    二、定义接口

    /**
     * @author zhaojiatao
     * @date 2019-07-14
     */
    public interface ICommonTransactionService {
    
        /**
         * 开启一个新事务来执行函数,有返回值;与外部事务互相隔离,发生异常只回滚本事务,不会互相影响
         * @param action
         * @param <T>
         * @urn
         */
        <T> T newTransactionExecuteAndReturnWithOutThrowable(Supplier<T> action);
    
        /**
         * 开启一个新事务来执行函数,有返回值;内部事务发生异常时会向外抛出异常,内部事务和外部事务均回滚
         * @param action
         * @param <T>
         * @urn
         */
        <T> T newTransactionExecuteAndReturnThrowable(Supplier<T> 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 CommonTransactionServiceImpl  implements ICommonTransactionService {
    
        @Autowired
        @Qualifier("transactionTemplateNew")
        TransactionTemplate transactionTemplateNew;
    
        @Override
        public <T> T newTransactionExecuteAndReturnWithOutThrowable(Supplier<T> action) {
            //执行带有返回值<Object>的事务管理
            return transactionTemplateNew.execute(transactionStatus-> {
                        try {
                            return action.get();
                        } catch (Exception e) {
                            log.error("newTransactionExecuteAndReturnNoThrowable发生异常",e);
                            //回滚
                            transactionStatus.setRollbackOnly();
                            return null;
                        }
                    });
        }
    
        @Override
        public <T> T newTransactionExecuteAndReturnThrowable(Supplier<T> action) {
            //执行带有返回值<Object>的事务管理
            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);
    
    
    
        }
  • 相关阅读:
    Unbutu之web环境部署——常用软件安装
    利用百度uaredirect.js判断手机终端并自动跳转
    原生Ajax附件上传简单实例
    shader glsl 函数图举例
    pixijs释放纹理的方法
    pixijs shader透明度设置方法
    pixijs 用canvas的方法
    threejs 解决模型缩小有黑边的解决方案
    threejs 透明模型遮挡后面模型解决方案
    javascript canvas 清除图片空白多余的方法
  • 原文地址:https://www.cnblogs.com/zhaojiatao/p/11238430.html
Copyright © 2020-2023  润新知