spring事务的隔离级别(透彻理解)

Posted THISISPAN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring事务的隔离级别(透彻理解)相关的知识,希望对你有一定的参考价值。

 

1.spring 事务这个东西,是轮子,每个service,都需要用到。所以干脆就做在框架层实现。

2.spring是怎么给你的service方法加事务的呢?jdk动态代理,会针对每个service类里的方法进行before(),atfer()开启和关闭事务。

3.所以@autowired注入进来的service都是受spring托管的,都附件了spring的功能。

怎么附加的呢?就是代理,每个service或者Controller类里@autowired进来的都是实际service target的代理类,并不是真的实际target。

只有spring这个代理类,才能享用spring的事务代理功能。

4.spring的事务传播只有在跨service类调用才能起作用,同个service类里事务方法调用是不会起作用的。因为spring事务是通过spring动态代理封装了target类啊

 

5.事务的传播级别,隔离级别。都是在@Transation注解的属性指定的。

 如:@Transactional(Propagation.NESTED)

 

6.事务传播级别:

常用的有(1)required:将两个不同方法包裹在一个事务里。因为是一个事务,所以要回滚全部回滚。

(2)required_new:在父事务里开启一个子事务。两个事务各自控制自己的回滚,彼此不受影响。父事务回滚不影响子事务是否回滚。

(3)required_nested:嵌套事务,这个和required_new子事务有点相像,但不同点是:

 

7) NESTED 
Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else. 
支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。 
嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。 

8) PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别 
它们非常 类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。使用PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA 事务管理器的支持。 
使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。 

 

   问题一:当二级事务被rollback一级事务会不会被rollback?
      答案是不会的,二级事务的rollback只针对自己。

   问题一:当二级事务被rollback一级事务会不会被rollback?
      答案是不会的,二级事务的rollback只针对自己。

   问题一:当二级事务被rollback一级事务会不会被rollback?
      答案是不会的,二级事务的rollback只针对自己。


 关于嵌套事物

  可能大家对PROPAGATION_NESTED还不怎么了解,觉得有必要再补充一下^_^!
PROPAGATION_NESTED: 嵌套事务类型,是相对上面提到的六种情况(上面的六种应该称为平面事务类型),打个比方我现在有一个事务主要有一下几部分:
      1,从A用户帐户里面减去100元钱
      2,往B用户帐户里面添加100元钱
       这样看和以前不同的事务可能没有什么区别,那我现在有点特殊的要求就是,A用户有3个帐户,B用户有2个帐户,现在我的要求就是只要再A用户的3个帐户里面任意一个减去100元,往B用户的两个帐户中任意一个里面增加100元就可以了!
       一旦你有这样的要求那嵌套事务类型就非常适合你!我们可以这样理解,
       一:将“从A用户帐户里面减去100元钱” 和 “往B用户帐户里面增加100元钱”我们暂时认为是一级事务操作
       二:将从A用户的3个帐户的任意一个帐户里面减钱看做是“从A用户帐户里面减去100元钱”这个一级事务的子事务(二级事务),同样把后面存钱的看成是另一个的二级事务。
      问题一:当二级事务被rollback一级事务会不会被rollback?
      答案是不会的,二级事务的rollback只针对自己。
      问题二:什么时候这个一级事务会commit,什么时候会被rollback呢?
      我们主要看二级里面出现的情况,当所有的二级事务被commit了并且一级事务没有失败的操作,那整个事务就算是一个成功的事务,这种情况整个事务会被commit。
当任意一个二级事务没有被commit那整个事务就是失败的,整个事务会被roolback。
还是拿上面的例子来说明吧!如果我在a的三个帐户里面减钱的操作都被二级事务给rollback了,也就是3个帐户里面都没有减钱成功,整个事务就失败了就会被rollback。如果A用户帐户三个帐户里面有一个可以扣钱而且B用户的两个帐户里面也有一个帐户可以增加钱,那整个事务就算成功的,会被 commit。
看了一下觉得上面的例子好像不是很深刻,看这个情况(A用户的3个帐户都是有信用额度的,也就是说可以超支,但是超支有金额限制)。不过原理是一样的,简单点也好说明一点,祝你好运!^_^ 

 

7)PROPAGATION_NESTED ,字面也可知道,nested,嵌套级别事务。该传播级别特征是,如果上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务。

那么什么是嵌套事务呢?很多人都不理解,我看过一些博客,都是有些理解偏差。

嵌套是子事务套在父事务中执行,子事务是父事务的一部分,在进入子事务之前,父事务建立一个回滚点,叫save point,然后执行子事务,这个子事务的执行也算是父事务的一部分,然后子事务执行结束,父事务继续执行。重点就在于那个save point。看几个问题就明了了:

如果子事务回滚,会发生什么? 

父事务会回滚到进入子事务前建立的save point,然后尝试其他的事务或者其他的业务逻辑,父事务之前的操作不会受到影响,更不会自动回滚。


如果父事务回滚,会发生什么? 

父事务回滚,子事务也会跟着回滚!为什么呢,因为父事务结束之前,子事务是不会提交的,我们说子事务是父事务的一部分,正是这个道理。那么:


事务的提交,是什么情况? 

是父事务先提交,然后子事务提交,还是子事务先提交,父事务再提交?答案是第二种情况,还是那句话,子事务是父事务的一部分,由父事务统一提交。

以上是关于spring事务的隔离级别(透彻理解)的主要内容,如果未能解决你的问题,请参考以下文章

Spring 事务类型与隔离级别

Spring框架默认事物隔离级别

Spring事务隔离级别:REQUIRES_NEW使用细节

Spring 有几种事务隔离级别?

Spring事务隔离级别

Spring事务的隔离级别