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

  • 相关阅读:
    5月7号 跨页面传值
    实体类、数据访问类、属性扩展
    完整修改删除,防止数据库字符串攻击
    ADO.NET 增、删、改、查
    类库、委托、is as运算符、泛型集合
    抽象类、接口
    多态、虚方法、重写
    访问修饰符、封装、继承
    面向对象基础知识
    Java Script 练习题
  • 原文地址:https://www.cnblogs.com/doagain/p/15068240.html
Copyright © 2011-2022 走看看