同一个类中调用方法spring事务注解@Transactional如何生效?

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

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

事务失效原因

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

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

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

myServiceImpl的对象变成了MyServiceImpl E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB9f78d9e5@5810,很明显是Spring通过CGLIB代理出来的对象。也就是说,InjectTest此时注入的是代理对象,而代理对象内部持有target目标对象。

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

整个过程类似这样:

左边代理对象,右边目标对象,调用代理对象,最终会委托到目标对象。

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

因为在add方法中通过this.sub()调用时,本质上根本不会走代理对象的逻辑,而目标对象内部并不存在事务相关的增强逻辑。

解决办法

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

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

Spring提供了AopContext。

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

具体代码是:

开源项目:

相关推荐
DyLatte6 小时前
AI 时代,最危险的不是被替代,而是努力不沉淀
前端·后端·程序员
神奇小汤圆6 小时前
架构师必备:CPU使用率不均匀排查
后端
神奇小汤圆6 小时前
Multi-Agent 执行闭环:AI Coding 真正进生产,要靠模型分工和工程护栏
后端
柒和远方6 小时前
从一次工程审查看 AI 学习产品的边界兜底:RAG 资料链路一致性实战
前端·后端·架构
亦暖筑序7 小时前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户34232323763177 小时前
GPIO控制与按键中断入门
后端
Gopher_HBo7 小时前
Go语言学习笔记(十五)Http响应
后端
kfaino8 小时前
码农的AI翻身(六)你好,我叫 Parameter
后端·aigc
掘金者阿豪8 小时前
把业务数据变成共享仪表盘:Metabase可视化与远程访问实践
前端·后端
猪猪拆迁队9 小时前
虚拟工厂仿真引擎的架构设计:让一条产线可编程、可观测、可干预
后端·ai编程