• Spring service本类中方法互相调用事物失效问题


    简介

    Spring事物利用的是AOP,动态代理采用CGLIB代理(默认,也可以用Proxy代理,但是Proxy代理效率低于CGLIB代理)。故只要弄懂Spring的AOP实现,就知道为什么service本类中方法互相调用会导致事物失效。

    失效案例

    service层代码

     public void  moneyTestOne(){
            //1.查询病人基本信息
            List<TBICXX> tbicxx = basisDao.getTBICXX();
            //2.根据CMZH更新TBMZFYHZ
            Integer TBMZFYHZCount = tbmzfyhzDao.updateByCMZH("王五", "1903003643");
            log.info("更新TBMZFYHZ影响行数{}",TBMZFYHZCount);
            this.moneyTestTwo();
    
        }
    
        @Transactional(rollbackFor = Exception.class,propagation=Propagation.REQUIRED)
        public void  moneyTestTwo(){
            //3.根据CMZH更新TBMZFYMXGH
            Integer integer = tbmzfymxghDao.updateByCMZH("王五", "2107000224");
            log.info("更新TBMZFYMXGH影响行数{}",integer);
            int i=2/0;
        }
    

    Test层代码

    /**
         * 测试其AOP事物(CGLIB代理):
         *   如moneyTestOne不添加事物,则moneyTestTwo事物及其一切传播行为将失效,这是由于spring的AOP的Cglib代理造成
         *   同理: moneyTestOne添加事物,moneyTestTwo事物及其一切传播行为也将失效,moneyTestTwo运行在moneyTestOne事物中。
         *   $$EnhancerBySpringCGLIB$$2364c0b7 代理
         **/
        @Test
        public void testTransationalPropagation(){
            log.info("测试开始,代理类{}",springTransactionSqlserverServiceImpl.getClass());
            springTransactionSqlserverServiceImpl.moneyTestOne();
        }
    

    运行前
    image
    运行后
    image
    结论
    moneyTestTwo方法事物并不生效,要想事物生效,只需要在moneyTestOne方法上加上事物注解(此方法同理会导致moneyTestTwo方法传播行为失效),

    失效分析

    Spring通过AopProxy接口,抽象了这两种实现,实现了一致的AOP方式:
    image
    现在看来,这种抽象同样带了一个缺陷,那就是抹杀了Cglib能够直接创建普通类的增强子类的能力。下图显示了Spring的AOP代理类的实际调用过程:
    image

    解决办法

    事物声明避免在一个类中互相调用,即moneyTestOne和moneyTestTwo要么都使用事物,要么直接分成两个类。

    Gitee代码地址

    https://gitee.com/zhuayng/foundation-study/tree/develop/SpringBootDemo/src/main/java/com/yxkj/springbootdemo/service/impl

    XFS
  • 相关阅读:
    .net core webapi发布到linux中
    封装EF,使用仓储模式所遇到的问题
    oracle取分组的前N条数据
    20141124
    搭建discuz论坛(2)
    安装apache mysql 论坛(一)
    L13 DNS
    L10 PUtty+SSH 访问vncviewer
    L12 samba服务器搭建
    L10 数据入站、转发、出站流程
  • 原文地址:https://www.cnblogs.com/xiaofengshan/p/15516714.html
Copyright © 2020-2023  润新知