1、具体有哪几种传播特性这里就不赘述了,网上一搜一大把,本文的目的是通过实验的方式验证几种传播特性嵌套之后的执行结果的探索。为了方便阐述,以下实验都将遵循,方法service1()中调用方法service2()或service3()的形式。
2、方法1设置成默认的传播特性(REQUIRED),方法2设置成MANDATORY,这种情况下,如果两个方法都正常执行,那么都会进行提交,这个有很好理解,因此MANDATORY指的是必须在一个事务中执行,如果有就使用当前事务,所以都得以提交。如果两个方法不论哪个方法抛出异常,则导致都不会被提交,就算是将方法2的异常进行捕获也一样,主要原因是他们用的是同一个事务。
方法1(REQUIRED) | 方法2(MANDATORY) | 最终结果 | |
---|---|---|---|
方法结果 | 正常 | 正常 | 都正常提交 |
正常 | 异常 | 回滚 | |
正常 | 异常(捕获) | 回滚 | |
异常 | 正常 | 回滚 |
3、方法1还是设置成默认值,方法2设置成NEVER,此时方法2会抛出异常,导致都无法提交事务,就不该这么用。
4、方法1依旧是默认值,方法2设置成REQUIRES_NEW,此种情况下,方法2会在自己的新的事务中执行,并将方法1的事务进行挂起,两个事务是相互独立的。如果都正常那么都会提交,如果方法2抛出异常但未捕获,那么都会回滚,毋庸置疑。如果方法1在调用方法2之后抛出异常,而方法2正常执行,那么方法1会回归,而方法2会提交,因为他们是独立的事务,因此各管各的,此种情况下也是和第5点中不一样的地方。
方法1(REQUIRED) | 方法2(REQUIRES_NEW) | 最终结果 | |
---|---|---|---|
方法结果 | 正常 | 正常 | 都正常提交 |
正常 | 异常 | 回滚 | |
正常 | 异常(捕获) | 方法1提交,方法2回滚 | |
异常 | 正常 | 方法1回滚,方法2提交 |
5、方法1始终是默认值,方法2设置成NESTED嵌套的方法,这个时候方法2的事务是方法1的一个子事务,并且存在一个安全点,如果子事务需要回滚,则会回滚到安全点的位置。如果都正常,那没什么好说的,都能正确提交。如果方法1正常,而方法2出现异常,这时就需要我们自己进行处理,看是否需要捕获异常,然后再catch中去调用方法3,形成一个分支的逻辑,方法2失败走方法3,会比较好使。现在说说第4点中提到的跟REQUIRES_NEW不同的地方在于,如果在调用方法2之后方法1抛异常了,那么都不会提交,子事务随着父事务的提交而提交,回滚而回滚,而REQUIRES_NEW情况下方法2还会提交。
方法1(REQUIRED) | 方法2(NESTED) | 最终结果 | |
---|---|---|---|
方法结果 | 正常 | 正常 | 都正常提交 |
正常 | 异常 | 回滚 | |
正常 | 异常(捕获) | 方法1提交,方法2回滚 | |
异常 | 正常 | 回滚 |