zoukankan      html  css  js  c++  java
  • Spring事务嵌套问题记录

    问题描述

    今天遇到一个spring事务嵌套的问题:

    **Transaction rolled back because it has been marked as rollback-only**

    问题复现

    ConsumerService.c() 中调用 ProducerService.p()

    ProducerService.p()中抛出一个运行时异常

    ConsumerService.c()catchp()的异常

    代码如下:

    public class ProducerServiceImpl implements ProducerService{
        @Autoware
        private UserService userService;
        @Transactional
        @Override
        public void p() {
            //保存
            userService.save(new User());
            //模拟异常
            throw new RuntimeException("eee");
        }
    }
    public class ConsumerServiceImpl implements ConsumerService{
        @Autoware
        private UserService userService;
        @Autoware
        private ProducerService producerService;
        @Transactional
        @Override
        public void c() {
            //保存
            userService.save(new User());
            //调用p() 并catch
            try{
            producerService.p();
            }catch(Exception e){
    
            }
        }
    }

    运行代码报错:

    org.springframework.transaction.UnexpectedRollbackException:   Transaction rolled back because it has been marked as rollback-only

    问题解决

    1. ProducerService.p()方法的@Transactional删除(没有其他方法调用c()
    2. ProducerService.p()方法上加@Transactional(propagation = Propagation.REQUIRES_NEW)开启新事务
    3. 如果不想改动@Transactional并且想不报错,代码改动如下
      public class ConsumerServiceImpl implements ConsumerService{
         @Autoware
         private UserService userService;
         @Autoware
         private ProducerService producerService;
         @Transactional
         @Override
         public void c() {
             //保存
             userService.save(new User());
             //调用p() 并catch
             try{
             producerService.p();
             }catch(Exception e){
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             }
         }
      }
    4. 如果不想改动@Transactional并且 想让producerService.p();不影响consumerService.c()方法,代码改动如下 (此时c()方法的代码将不会回滚!)
      public class ConsumerServiceImpl implements ConsumerService{
         @Autoware
         private UserService userService;
         @Autoware
         private ProducerService producerService;
         @Transactional
         @Override
         public void c() {
             try{   
                 //保存
                 userService.save(new User());
                 //调用p() 并catch
                 try{
                    producerService.p();
                 }catch(Exception e){
      
                 }
             }catch(Exception e){
                   TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
         }
         }
      }

    源码分析

    todo

  • 相关阅读:
    CentOS 7下启动postfix服务报错:fatal: parameter inet_interfaces: no local interface found for ::1
    CentOS 7设置ulimit不生效的问题解决
    GitLab目录迁移方法
    GitLab查询当前版本
    CentOS 7安装Gitlab时报错:undefined method `downcase' for nil:NilClass
    .NET Core的依赖注入[1]: 控制反转
    .NET Core跨平台的奥秘[下篇]:全新的布局
    .NET Core跨平台的奥秘[中篇]:复用之殇
    .NET Core跨平台的奥秘[上篇]:历史的枷锁
    .NET Core多平台开发体验[4]: Docker
  • 原文地址:https://www.cnblogs.com/doagain/p/15068240.html
Copyright © 2011-2022 走看看