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

  • 相关阅读:
    nodejs中处理回调函数的异常
    Web前端开发十日谈
    Android 高仿微信6.0主界面 带你玩转切换图标变色
    Android EventBus源码解析 带你深入理解EventBus
    Android EventBus实战 没听过你就out了
    究竟谁在绑架中国的4G政策?
    Android 实战美女拼图游戏 你能坚持到第几关
    oracle学习
    his使用-重置密码
    oracle中的DDL、DML、DCL
  • 原文地址:https://www.cnblogs.com/doagain/p/15068240.html
Copyright © 2011-2022 走看看