zoukankan      html  css  js  c++  java
  • spring事务传播性理解

    什么是spring的事务传播性

    个人的理解,

    首先先说一下事务传播性,事务传播性就是,事务中还包括另外的事务,事务之间是怎么相互影响,然后如何执行的,这就是事务传播性

    spring事务传播性就是spring中是如何去规定事务是如何执行的,情况如下:

    public class DemoServiceA {
        //事务A
        @Transactional(propagation=Propagation.REQUIRED)//对于外层事务来说(相对的,如果demoMthodA加到demoMthodC中,demoMthodC就是外层了),只区分包括事务没有
        public void demoMethodA() {  
            code1; 
            demoServiceB.demoMethodB();// A事务中加入了 B事务
            code4;
        }
    }
    
    public class DemoServiceB {
        //事务B
        @Transactional(propagation=待定...)
        public void demoMethodB() {   
            code2;
            code3;
        }
    }

    待定的情况如下

    七个事务传播属性

     PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
     PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
     PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
     PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
     PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
     PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
     PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

    详细点就是下面:

    1: REQUIRED
    
    加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务
    
    比如说,DemoServiceB.demoMethodB的事务级别定义为REQUIRED, 那么由于执行DemoServiceA.demoMethodA的时候,
    
    DemoServiceA.demoMethodA已经起了事务,这时调用DemoServiceB.demoMethodB,DemoServiceB.demoMethodB看到自己已经运行在DemoServiceA.demoMethodA
    
    的事务内部,就不再起新的事务。而假如DemoServiceA.demoMethodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。
    
    这样,在DemoServiceA.demoMethodA或者在DemoServiceB.demoMethodB内的任何地方出现异常,事务都会被回滚。即使DemoServiceB.demoMethodB的事务已经被
    
    提交,但是DemoServiceA.demoMethodA在接下来fail要回滚,DemoServiceB.demoMethodB也要回滚
    
    2: SUPPORTS
    
    如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行
    
    3: MANDATORY
    
    必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常
    
    4: REQUIRES_NEW
    
    这个就比较绕口了。 比如我们设计DemoServiceA.demoMethodA的事务级别为REQUIRED,DemoServiceB.demoMethodB的事务级别为REQUIRES_NEW,
    
    那么当执行到DemoServiceB.demoMethodB的时候,DemoServiceA.demoMethodA所在的事务就会挂起,DemoServiceB.demoMethodB会起一个新的事务,等待DemoServiceB.demoMethodB的事务完成以后,
    
    他才继续执行。他与REQUIRED 的事务区别在于事务的回滚程度了。因为DemoServiceB.demoMethodB是新起一个事务,那么就是存在
    
    两个不同的事务。如果DemoServiceB.demoMethodB已经提交,那么DemoServiceA.demoMethodA失败回滚,DemoServiceB.demoMethodB是不会回滚的。如果DemoServiceB.demoMethodB失败回滚,
    
    如果他抛出的异常被DemoServiceA.demoMethodA捕获,DemoServiceA.demoMethodA事务仍然可能提交。
    
    5: NOT_SUPPORTED
    
    当前不支持事务。比如DemoServiceA.demoMethodA的事务级别是REQUIRED ,而DemoServiceB.demoMethodB的事务级别是NOT_SUPPORTED ,
    
    那么当执行到DemoServiceB.demoMethodB时,DemoServiceA.demoMethodA的事务挂起,而他以非事务的状态运行完,再继续DemoServiceA.demoMethodA的事务。
    
    6: NEVER
    
    不能在事务中运行。假设DemoServiceA.demoMethodA的事务级别是REQUIRED, 而DemoServiceB.demoMethodB的事务级别是NEVER ,
    
    那么DemoServiceB.demoMethodB就要抛出异常了。
    
    7: NESTED
    
    理解Nested的关键是savepoint。他与REQUIRES_NEW的区别是,REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,
    
    而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。
    
    复制代码

    总的来说

    1.当事务中方法中还有事务的时候,多事务是如何相互影响,如何去执行的,spring的事务传播性就规定了细节,例如如何回滚问题,7中传播级别

    2.A事务中有B事务,要考虑A,B事务如何执行,A中只需要考虑有没有事务就ok,B的话就需要具体看是那种事务传播性了。

  • 相关阅读:
    一文让你快速入门pytest框架
    Python classmethod 修饰符
    python三种导入模块的方法
    18 | 眼前一亮:带你玩转GUI自动化的测试报告
    20193103《Python程序设计》实验二报告
    20193103陈柏维《Python程序设计》实验四报告
    20193103《Python程序设计》实验三报告
    20193103陈柏维《Python程序设计》实验一报告
    一种有效的编程思路
    一些希望实现的项目
  • 原文地址:https://www.cnblogs.com/longsanshi/p/8620250.html
Copyright © 2011-2022 走看看