同类中spring事务注解@Transactional生效问题(转)

作者:bravo1988
链接:https://www.zhihu.com/question/469242635/answer/3436736540
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

评论区的小伙伴提醒了我,首先还是先把问题描述清楚:

sub方法事务有效

sub方法事务失效

要解答这个问题,要分两步走:

  • 同一个类中,方法A调用方法B,为什么会导致B事务失效
  • 如何避免事务失效

事务失效原因

我们先来看一个正常的依赖注入

InjectTest注入了MyServiceImpl,可以调用MyServiceImpl#doSomething()。

但是,当我们给MyServiceImpl#doSomething()加上@Transactional注解后:

myServiceImpl的对象变成了MyServiceImpl$$EnhancerBySpringCGLIB$$9f78d9e5@5810,很明显是Spring通过CGLIB代理出来的对象。也就是说,InjectTest此时注入的是代理对象,而代理对象内部持有target目标对象。

本次方法调用最终会到达目标对象,也就是真正的MyServiceImpl:

整个过程类似这样:

sub加了@Transactional,所以Spring为MyService创建代理对象,代理对象内部有事务增强

回到我们的问题:同一个类中,A方法调用B方法(事务方法)为什么会导致B方法事务失效呢?

 

因为在add方法中通过this.sub()调用时,本质上根本不会走代理对象的逻辑。

所有调用都在目标对象内部完成,与代理对象无关,也用不上事务增强逻辑

解决办法

知道原因后,就很好解决了。最简单的方法是使用AopContext获取实际的代理对象。

那么,怎么在目标对象中获取到实际的代理对象proxy呢?

Spring提供了AopContext。

开启exposeProxty=true以后,Spring会在AopContext中共享当前代理对象(本质是在本次请求中通过ThreadLocal共享代理对象)。

具体代码是:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值