spring事务传播性理解

Posted longtengdama

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的话就需要具体看是那种事务传播性了。







以上是关于spring事务传播性理解的主要内容,如果未能解决你的问题,请参考以下文章

理解Spring的事务传播级别

实战Spring事务传播性与隔离性

Spring事务传播性与隔离级别

Spring的事务传播性

Spring事务传播性

Spring事务传播性