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

  • 相关阅读:
    CSS基础
    数据库优化之SQL Server
    压力测试与系统调优
    JBoss架构分析
    JBoss基本配置
    深入了解硬盘结构
    EJB2与EJB3架构对比
    JBoss高级配置
    病毒分类及病毒命名规则详解
    深入讲解防火墙的概念原理与实现
  • 原文地址:https://www.cnblogs.com/doagain/p/15068240.html
Copyright © 2011-2022 走看看