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

  • 相关阅读:
    在为知笔记中使用JQuery
    解决Wireshark安装Npcap组件失败
    SSL/TLS抓包出现提示Ignored Unknown Record
    Metasploit中aggregator插件无法使用
    Metasploit运行环境内存不要低于2GB
    如何查看抓包文件所使用的捕获过滤器
    Nvidia的CUDA库现在恢复使用了
    Metasploit远程调用Nessus出错
    Nessus更新到8.3.0
    Kali Linux安装字典StarDict
  • 原文地址:https://www.cnblogs.com/doagain/p/15068240.html
Copyright © 2011-2022 走看看