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

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

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

事务失效原因

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

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

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

myServiceImpl的对象变成了MyServiceImpl <math xmlns="http://www.w3.org/1998/Math/MathML"> E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB </math>EnhancerBySpringCGLIB9f78d9e5@5810,很明显是Spring通过CGLIB代理出来的对象。也就是说,InjectTest此时注入的是代理对象,而代理对象内部持有target目标对象。

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

整个过程类似这样:

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

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

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

解决办法

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

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

Spring提供了AopContext。

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

具体代码是:

开源项目:

相关推荐
Walter先生1 小时前
WebSocket 连接池生产级实现:实时行情高可用与负载均衡
后端·websocket·架构
虹梦未来2 小时前
【开发心得】在SpringBoot体系中正确使用redisConfig
java·spring boot·spring
skiy2 小时前
Spring Framework 中文官方文档
java·后端·spring
jserTang2 小时前
Claude Code 源码深度解析 - 前言
前端·javascript·后端
AI大法师2 小时前
复盘 TikTok 品牌升级:动态品牌系统应该怎么理解和落地
大数据·人工智能·设计模式
清溪5492 小时前
Damn Vulnerable Web Application(中)
后端
清溪5493 小时前
Damn Vulnerable Web Application(上)
后端
掘金码甲哥3 小时前
AI编程智能体登味太浓了,必须治一治!
后端
StackNoOverflow3 小时前
SpringCloud的声明式服务调用 Feign 全面解析
后端·spring·spring cloud
木心术13 小时前
RESTful API设计最佳实践:构建可扩展的后端服务
后端·restful