关于加@Transactional注解的方法之间调用,事务是否生效的问题

系列文章目录

前言

一、关于加@Transactional注解的方法之间调用,事务是否生效的问题

关于加@Transactional注解的方法之间调用,事务是否生效的问题

二、AopContxt.currentProxy()

1.AopContxt.currentProxy()

AopContxt.currentProxy()

使用AopContxt.currentProxy()方法可获取当前类的代理对象(是通过StaticUnadvisedExposedInterceptor或DynamicUnadvisedExposedInterceptor或JdkDynamicAopProxy#invoke中设置的,@EnableAspectJAutoProxy#exposeProxy可设置为true,将当前的aop对象暴露到AopContext的ThreadLocal变量currentProxy中)

在使用@Transactional注解声明事务时,会有以下四种情况:

在不同类中,事务方法A调用非事务方法B,事务具有传播性,事务生效;

在不同类中,非事务方法A调用事务方法B,事务生效;

在同一个类中,事务方法A调用非事务方法B,事务生效;

在同一个类中,非事务方法A调用事务方法B,事务失效,这是由于使用Spring AOP代理造成的,只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。

解决办法:

采用AopContext.currentProxy().方法B名()来进行调用
ApplicationContext.getBean()
在当前类中注入自己
使用手动事务
如果该类存在@Async异步任务方法,那么@Async方法应该使用第3种方式并且在引入的自身代理对象上加上@Lazy注解,让其再进行代理封装(看这里: Spring AOP入门以及基于XML的Spring AOP配置的深入学习与使用【两万字】_刘Java的博客-CSDN博客)

思考:为什么在被代理类的方法中调用被代理的其它方法时,不经过增强方法呢?

这是由aop的实现机制决定的,spring aop抽象出了TargetSource接口(从中可以获取target目标对象),当外部通过调用代理对象的方法时,就会经过MethodInterceptor方法拦截器(增强方法),当所有的方法拦截器都调用完了(责任链模式),就会从代理配置(ProxyFactory->ProxyCreatorSupport->AdvisedSupport中维护targetSource)的TargetSource中获取到目标对象,然后使用反射调用该目标对象的目标方法,也就是最终目标对象执行时,其实这个时候已经不是代理对象了,此时是目标对象!那么反射方法执行时,方法中的this,就是目标对象,那在一个成员方法中调用类中的另外一个成员方法(此时省略了this),省略的这个this是目标对象,而不是代理对象,因此被调用的另外一个成员方法时,是不会经过增强方法的(方法拦截器)。

2.Spring AOP入门以及基于XML的Spring AOP配置的深入学习与使用【两万字】

Spring AOP入门以及基于XML的Spring AOP配置的深入学习与使用【两万字】

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值