声明式事务基于注解@Transactional的理解

事务分为编程式事务 与 声明式事务 这里描述常用的声明式事务的原理。

@Transactional 实现机制:

  当在方法上使用@Transactional 时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,根据@Transactional 的属性配置信息,这个代理对象决定该声明@Transactional 的目标方法是否由拦截器 TransactionInterceptor 来使用拦截,在 TransactionInterceptor 拦截时,会在在目标方法开始执行之前创建并加入事务,并执行目标方法的逻辑, 最后根据执行情况是否出现异常决定提交或回滚事务。


@Transactional 中相关参数说

name        :当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。

propagation   :事务的传播行为,默认值为 REQUIRED。

isolation      :事务的隔离度,默认值采用 DEFAULT。

timeout             :事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。

read-only    :指定事务是否为只读事务,默认false 为了忽略那些不需要事务的方法,如读取数据可以设置read-only为true。

rollback-for      :用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。

no-rollback- for:抛出 no-rollback-for 指定的异常类型,不回滚事务。

(重点说明)propagation : 事务的传播行为 

Propagation.REQUIRED(默认):如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。

Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。

Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。

Propagation.REQUIRES_NEW:重新创建一个新的事务,如果当前存在事务,暂停当前的事务。

Propagation.NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,暂停当前的事务。

Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。

Propagation.NESTED: Propagation.REQUIRED 效果一样。


不会执行事务的场景:懂原理才能知道为什么不执行!!

为什么不启用事务的排查逻辑:

1、public:SpringAOP中涉及的核心类CglibAopProxy 或者 JdkDynamicAopProxy 无法获取@Transactional 的相关配置,因为该方法非Public 所以获取不到。

2、try/catch:核心类找到了你@Transactional 的配置,但你在方法里catch 掉了,所以事务拦截器拦截的时候抓不到异常导致无法回滚

3、同类中自调用:找到了,也没有catch.但还是没有回滚,看看是不是在同一个类中形成了自调用(同类中方法事务A调用事务方法B)这里可以参考IBM的这个博客

4、propagation:找到没也没catch也无自调用,检查Propagation 参数是否配置了不启用事务的参数

5、回滚异常检测:检查rollbackFor 以及 noRollbackFor 这里检查的异常是否有问题。

 


 

参考文章:

https://blog.csdn.net/nextyu/article/details/78669997  《Spring Boot 中使用 @Transactional 注解配置事务管理》

https://www.ibm.com/developerworks/cn/java/j-master-spring-transactional-use/index.html 《透彻的掌握 Spring 中@transactional 的使用》

https://docs.spring.io/spring/docs/4.3.13.RELEASE/spring-framework-reference/htmlsingle/#transaction-declarative-annotations

《Spring框架参考文档》

猜你喜欢

转载自www.cnblogs.com/lanSeGeDiao/p/10919415.html