启用Spring事务管理@EnableTransactionManagement示例解析
Spring事务管理
Spring事务管理可以通过@EnableTransactionManagement注解开启,通过对@EnableTransactionManagement的分析,就能揭开Spring启用事务的底层机制。
直接开始源码分析。
@EnableTransactionManagement注解作用在配置类上,引入了TransactionManagementConfigurationSelector,这个先放一放,后面再分析。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {我们先看一下他定义的方法:
boolean proxyTargetClass() default false; AdviceMode mode() default AdviceMode.PROXY; int order() default Ordered.LOWEST_PRECEDENCE;
定义了3个方法,我们逐个分析一下:
proxyTargetClass
boolean proxyTargetClass() default false;
Indicate whether subclass-based (CGLIB) proxies are to be created (true) as opposed to standard Java interface-based proxies (false). The default is false. Applicable only if mode() is set to AdviceMode.PROXY.
Note that setting this attribute to true will affect all Spring-managed beans requiring proxying, not just those marked with @Transactional. For example, other beans marked with Spring's @Async annotation will be upgraded to subclass proxying at the same time. This approach has no negative impact in practice unless one is explicitly expecting one type of proxy vs another, e.g. in tests.
决定采用CGLIB的方式(设置为TRUE)、还是JDK方式创建代理类(设置为false),默认值为false。仅在Mode设置为PROXY的情况下才有效。
需要注意的是设置为true后会影响所有的的被Spring管理的代理类的创建方式,不止是@Transactional注解标注的类。比如,其他的被@Async标注的类也会被影响。
大概意思是说,在Mode设置为PROXY的情况下,这个参数决定代理类的创建方式,设置为true则通过CGLIB方式创建代理对象,设置为false则通过JDK方式创建代理对象。默认是通过JDK方式创建。
但是为什么设置为true后会影响到不止是@Transactional注解标注的类,而是会影响到整个Spring管理的bean呢?待考证。
mode
AdviceMode mode() default AdviceMode.PROXY;
Indicate how transactional advice should be applied.
The default is AdviceMode.PROXY. Please note that proxy mode allows for interception of calls through the proxy only. Local calls within the same class cannot get intercepted that way; an Transactional annotation on such a method within a local call will be ignored since Spring's interceptor does not even kick in for such a runtime scenario. For a more advanced mode of interception, consider switching this to AdviceMode.ASPECTJ.
事务advice(AOP概念)的实现方式,默认值为PXOXY,注意PROXY模式只允许通过代理方式调用,本地调用不生效。事务注解方法如果通过本地调用的话,事务处理不会生效,因为这种情况下Spring AOP的拦截机制不会生效。
JavaDoc说的很明白了,也是我们在其他文章里面提到过的,如果在同一个类中一个方法A调用被@Transactional标注的另外一个方法B的话,方法B的@Transactional不会生效,因为这种情况下的调用就属于这里所说的“本地调用”,没有调用到代理类,AOP拦截机制不会生效,因此方法B不会被AOP增强,因此事务不会生效。
Ordered
很熟悉的AOP增强概念,当多个拦截器生效的情况下,决定其顺序。
int order() default Ordered.LOWEST_PRECEDENCE;
好了,今天就到这里,由于Spring源码本身比较复杂,一次分析太多、文章太大的话,会比较乱,所以,改变一下思路,一篇文章只说一个概念,控制文章的篇幅,增强可读性。
以上就是启用Spring事务管理@EnableTransactionManagement示例解析的详细内容,更多关于Spring事务管理的资料请关注脚本之家其它相关文章!
相关文章
Spring boot中使用ElasticSearch的方法详解
这篇文章主要给大家介绍了关于Spring boot中使用ElasticSearch的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-01-01
Spring Boot 整合mybatis 与 swagger2
之前使用springMVC+spring+mybatis,总是被一些繁琐的xml配置,还经常出错,下面把以前的一些ssm项目改成了spring boot + mybatis,相对于来说优点太明显了,具体内容详情大家通过本文学习吧2017-08-08
SpringBoot+Response如何统一返回result结果集
这篇文章主要介绍了SpringBoot+Response如何统一返回result结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-05-05
Mybatis-Plus中updateById方法不能更新空值问题解决
本文主要介绍了Mybatis-Plus中updateById方法不能更新空值问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2022-08-08


最新评论