Spring事务传播级别理解

  • REQUIRED: 默认事务传播级别,如果当前没有事务,就新建一个事务,如果当前存在事务,就加入这个事务

    • 内外为同一个事务,外部回滚内部也回滚,内部回滚外部也回滚

    • public void testMain(){
          A(a1);  //调用A入参a1
          testB();    //调用testB
      }
      @Transactional(propagation = Propagation.REQUIRED)
      public void testB(){
          B(b1);  //调用B入参b1
          throw Exception;     //发生异常抛出
          B(b2);  //调用B入参b2
      }
      

      上面a1会存入,b1b2会回滚,因为testB没有事务就新建一个事务

  • SUPPORTS:当前存在事务则加入当前事务,如果当前没有事务,就以非事务方法执行

    • public void testMain(){
          A(a1);  //调用A入参a1
          testB();    //调用testB
      }
      @Transactional(propagation = Propagation.SUPPORTS)
      public void testB(){
          B(b1);  //调用B入参b1
          throw Exception;     //发生异常抛出
          B(b2);  //调用B入参b2
      }
      

      这种情况下a1、b1、会存入,b2不会存,因为调用方testmain没有开启事务,testb是SUPPORTS,即以非事务方法执行

  • MANDATORY:当前存在事务则加入当前事务,如果当前没有事务,就抛出异常

    • public void testMain(){
          A(a1);  //调用A入参a1
          testB();    //调用testB
      }
      @Transactional(propagation = Propagation.MANDATORY)
      public void testB(){
          B(b1);  //调用B入参b1
          throw Exception;     //发生异常抛出
          B(b2);  //调用B入参b2
      }
      

      a1会存储,b1b2不会存储,之所以b1没有存储的是因为MANDATORY只要是非事务就会抛出异常,还没走到b1就报错了,如果testmain设置了required的话就会以事务方式运行,可以正常回滚

  • REQUIRES_NEW: 创建一个新事务,如果当前存在事务,则挂起该事务

    • @Transactional(propagation = Propagation.REQUIRED)
      public void testMain(){
          A(a1);  //调用A入参a1
          testB();    //调用testB
          throw Exception;     //发生异常抛出
      }
      @Transactional(propagation = Propagation.REQUIRES_NEW)
      public void testB(){
          B(b1);  //调用B入参b1
          B(b2);  //调用B入参b2
      }
      

      上面a1会回滚,b1b2不会回滚,因为开启了新的事务,即外部回滚内部不回滚,内部回滚外部不回滚

  • NOT_SUPPORTED:始终以非事务方式执行,如果当前存在事务,则挂起当前事务

    • @Transactional(propagation = Propagation.REQUIRED)
      public void testMain(){
          A(a1);  //调用A入参a1
          testB();    //调用testB
      }
      @Transactional(propagation = Propagation.NOT_SUPPORTED)
      public void testB(){
          B(b1);  //调用B入参b1
          throw Exception;     //发生异常抛出
          B(b2);  //调用B入参b2
      }
      

      a1b2不会存储,b1会存储,因为testb没有事务,当b1执行完后抛出异常会导致testmain回滚,导致a1也不会存储

  • NEVER:不使用事务,如果当前事务存在则抛出异常

    • @Transactional(propagation = Propagation.REQUIRED)
      public void testMain(){
          A(a1);  //调用A入参a1
          testB();    //调用testB
      }
      @Transactional(propagation = Propagation.NEVER)
      public void testB(){
          B(b1);  //调用B入参b1
          B(b2);  //调用B入参b2
      }
      

      上面a1b1b2都不会存储,因为testb会抛出异常导致testmain回滚

  • NESTED:如果当前存在事务,则在嵌套事务中执行,否则和REQUIRED的操作一样(开启一个事务)

    • @Transactional(propagation = Propagation.REQUIRED)
      public void testMain(){
          A(a1);  //调用A入参a1
          testB();    //调用testB
          throw Exception;     //发生异常抛出
      }
      @Transactional(propagation = Propagation.NESTED)
      public void testB(){
          B(b1);  //调用B入参b1
          B(b2);  //调用B入参b2
      }
      

      上面都不会存储,因为testb子事务会跟着testmain父事务的回滚而回滚

    • @Transactional(propagation = Propagation.REQUIRED)
      public void testMain(){
          A(a1);  //调用A入参a1
          try{
              testB();    //调用testB
          }catch(Exception e){
      
          }
          A(a2);
      }
      @Transactional(propagation = Propagation.NESTED)
      public void testB(){
          B(b1);  //调用B入参b1
          throw Exception;     //发生异常抛出
          B(b2);  //调用B入参b2
      }
      

      a1a2会存储,b1b2会回滚,因为父事务catch了异常所以只有子事务回滚了,如果这里的testb传播级别是REQUIRED的话都不会存储,因为是在同一个事务中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值