• spring事务传播机制


    事务是我们开发中经常用到的,那么spring中的事务是怎么样的呢?可以用注解@Transactional注解来进行对spring事务的管理,注意:@Transactional注解只能放在public方法上面。他有一个Propagation属性,是用来控制事务的传播属性,主要有如下七个属性。

    1.REQUIRED,这个是默认的属性
    Support a current transaction, create a new one if none exists.

    支持当前事务,如果当前没有事务,则新建事务。

    如果当前存在事务,则加入当前事务,合并成一个事务。


    2.MANDATORY
    Support a current transaction, throw an exception if none exists.

    支持当前事务,如果当前没有事务,就抛出异常。

    3.NEVER
    Execute non-transactionally, throw an exception if a transaction exists.
    以非事务方式执行,如果当前存在事务,则抛出异常。

    4.NOT_SUPPORTED
    Execute non-transactionally, suspend the current transaction if one exists.
    以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。  

    5.REQUIRES_NEW
    Create a new transaction, suspend the current transaction if one exists.
    新建事务,如果当前存在事务,把当前事务挂起。


    6.SUPPORTS
    Support a current transaction, execute non-transactionally if none exists.
    支持当前事务,如果当前没有事务,就以非事务方式执行。

    7.NESTED
    Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.

    存在事务则运行在嵌套事务中,不存在则创建一个事务。

    嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

    其中比较难理解的就是NOT_SUPPORTED NESTED ,现举个例子如下:

    如果ServiceA.methodA的事务级别是PROPAGATION_REQUIRED

    package com.haoqiangwang.service;
    
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.annotation.Resource;
    
    @Service
    public class ServiceA {
    
        @Resource
        private ServiceB serviceB;
    
        @Transactional(propagation = Propagation.REQUIRED)
        public void methodA(){
            serviceB.methodB();
        }
    }

    而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED ,

    package com.haoqiangwang.service;
    
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class ServiceB {
    
        @Transactional(propagation = Propagation.NOT_SUPPORTED)
        public void methodB(){
    
            //此时方法以非事务的状态运行
        }
    }

    那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而他以非事务的状态运行完,再继续ServiceA.methodA的事务。


    而ServiceB.methodB的事务级别为PROPAGATION_NESTED,

    package com.haoqiangwang.service;
    
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class ServiceB {
    
        @Transactional(propagation = Propagation.NESTED)
        public void methodB(){
    
            //此时方法以新的事务的状态运行,此事务是调用它事务的子事务
        }
    }

    那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的子事务并设置savepoint,等待ServiceB.methodB的事务完成以后,他才继续执行。因为ServiceB.methodB是外部事务的子事务,那么
    1、如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB也将回滚。
    2、如果ServiceB.methodB失败回滚,如果他抛出的异常被ServiceA.methodA的try..catch捕获并处理,ServiceA.methodA事务仍然可能提交;如果他抛出的异常未被ServiceA.methodA捕获处理,ServiceA.methodA事务将回滚。

  • 相关阅读:
    P1141零一迷宫
    P1219八皇后
    P1233木棍加工
    三 Struts2 添加返回数据
    二 Struts2 接收数据
    一 Struts2 开发流程
    12-tinyMCE文本编辑器+图片上传预览+页面倒计时自动跳转
    11-page分页原理
    10-ajax技术简介
    9-文件上传和下载
  • 原文地址:https://www.cnblogs.com/wanghq1994/p/12102959.html
Copyright © 2020-2023  润新知