为什么同一个类中方法互调,@Transacational会失效
摘要今天我在 Spring 开发中遇到了一个场景明明给方法加了Transactional注解但在同一个类中通过this调用该方法时事务却神奇地消失了本文将带你深入 Spring AOP 底层来解释这一问题一.问题现象在 Spring 开发中当一个 Service 类中的非事务方法Method A直接调用同类中标注了Transactional的事务方法Method B时事务注解往往不会生效。Service public class UserService { Autowired private UserMapper userMapper; // 外部入口方法无事务注解 public void createUser() { System.out.println(Step 1: 执行前置逻辑); // ❌ 问题点内部自调用 this.saveUser(); System.out.println(Step 3: 执行后置逻辑); } // 目标事务方法 Transactional public void saveUser() { System.out.println(Step 2: 保存用户数据); userMapper.insert(new User()); // 模拟异常 throw new RuntimeException(DB Error); } }预期行为saveUser抛出异常数据库操作回滚。实际行为异常被抛出但数据库中的数据已被提交事务未生效。这是为什么二.核心原理AOP动态代理机制Spring 的声明式事务管理基于AOP面向切面编程实现其底层依赖动态代理Dynamic Proxy技术。2.1 代理对象的创建当 Spring 容器启动并扫描到标注了Transactional的 Bean如UserService时Spring 不会直接将原始类Target Object注册到容器中而是会创建一个代理对象Proxy Object。原始对象Target包含真实的业务逻辑代码。代理对象Proxy包裹在原始对象外层包含了事务拦截器Transaction Interceptor。容器引用当我们使用Autowired注入UserService时实际注入的是代理对象。2.2 正常调用链路外部调用当外部类调用userService.createUser()时调用链路如下Client调用Proxy.createUser()。Proxy中的拦截器链被触发。由于createUser无事务注解拦截器直接放行。Proxy调用Target.createUser()原始对象方法。在Target.createUser()内部执行this.saveUser()。关键点此时的this指向的是Target原始对象而非Proxy。因此调用直接进入Target.saveUser()完全绕过了 Proxy 中的事务拦截器。Transactional注解定义的“开启事务”、“异常回滚”等逻辑从未被执行。结论Transactional生效的前提是方法调用必须经过代理对象。同类内部的this调用属于对象内部的方法栈帧切换不经过代理层导致 AOP 切面无法织入。三.源码级分析Spring AOP 的核心逻辑位于org.springframework.aop.framework.ReflectiveMethodInvocation。当调用经过代理时执行流程为JdkDynamicAopProxy.invoke()(或 CGLIB 代理) 被调用。构建InterceptorChain拦截器链其中包含TransactionInterceptor。MethodInvocation.proceed()依次执行拦截器。TransactionInterceptor执行invokeWithinTransaction()在此方法中获取PlatformTransactionManager。调用txManager.getTransaction()开启事务。执行目标方法invocation.proceedWithInvocation()。根据执行结果 commit 或 rollback。当发生自调用Self-Invocation时JVM 直接在堆栈中执行Target.methodA-Target.methodB。这是一个纯粹的 Java 内部方法调用没有任何字节码增强或代理拦截介入因此TransactionInterceptor根本没有机会运行。四. 解决方案要解决此问题必须强制让方法调用重新经过代理对象。解决办法暴露代理对象AopContext利用 Spring 提供的AopContext获取当前线程绑定的代理对象。第一步开启配置在配置类或启动类上启用exposeProxyConfiguration EnableAspectJAutoProxy(exposeProxy true) public class AppConfig { }第二步获取代理调用Service public class UserService { public void createUser() { System.out.println(Step 1: 执行前置逻辑); // 获取当前代理对象 UserService proxy (UserService) AopContext.currentProxy(); // 通过代理对象调用 proxy.saveUser(); } Transactional public void saveUser() { // ... } }原理AopContext将当前的 Proxy 对象绑定到ThreadLocal中允许在目标方法内部获取它。缺点代码耦合了 Spring 框架 API (AopContext)且需要修改全局配置侵入性较强。五. 进阶思考事务传播行为即使解决了失效问题还需注意事务传播行为Propagation Behavior的影响。假设createUser也被加上了TransactionalTransactional // 默认 propagation REQUIRED public void createUser() { self.saveUser(); // saveUser 也是 Transactional (REQUIRED) }默认情况 (REQUIRED)saveUser会加入到createUser已有的事务中。两者共用同一个数据库连接和事务上下文。此时若saveUser抛出异常整个createUser的事务都会回滚。独立事务 (REQUIRES_NEW)如果希望saveUser拥有独立的事务即它的提交/回滚不影响外层或者外层失败不影响它已提交的数据需修改注解Transactional(propagation Propagation.REQUIRES_NEW) public void saveUser() { ... }此时代理对象会在调用saveUser时挂起Suspend外层事务创建一个全新的物理事务。六.总结核心结论Spring 的事务管理依赖于代理模式。任何绕过代理对象的直接方法调用尤其是this调用都会导致 AOP 增强逻辑包括事务、日志、安全校验等失效。在设计业务逻辑时应尽量避免同类内的自调用或通过上述方案强制走代理链路。

相关新闻

Spring 事务失效 8 大场景!一篇彻底搞懂 @Transactional 不生效

Spring 事务失效 8 大场景!一篇彻底搞懂 @Transactional 不生效

在开发中,Transactional 可以说是最常用、也最容易踩坑的注解。明明加了注解,结果异常不回滚、事务不生效,数据错了还很难排查。今天这篇把 Spring 事务失效 8 大高频场景 一次性讲透,每个场景都给你 错误代码 正确代码&#xff…

2026/5/17 7:25:33 阅读更多 →
网安初学日记|永恒之蓝(MS17-010)漏洞攻击实操记录

网安初学日记|永恒之蓝(MS17-010)漏洞攻击实操记录

前言作为网安新手,今天正式上手实操了永恒之蓝(MS17-010)漏洞的完整流程——从nmap漏洞扫描,到利用漏洞攻击并控制目标虚拟机,每一步都充满了新鲜感,也深刻体会到网安学习的严谨性。特此记录下来&#xff0…

2026/5/17 11:53:20 阅读更多 →
AI数字人制作成本高?2026年十大工具如何破解选型难题

AI数字人制作成本高?2026年十大工具如何破解选型难题

在数字内容快速发展的当下,许多企业和个人在数字人制作的道路上,都面临着成本与选择的双重挑战。如何找到合适的工具,降低制作成本,成为众多关注数字人发展的用户心中的疑问。从市场整体来看,2026年数字人行业的技术门…

2026/7/3 21:41:11 阅读更多 →

最新新闻

STM32F207ZG与25CSM04 Page EEPROM高速数据存储方案

STM32F207ZG与25CSM04 Page EEPROM高速数据存储方案

1. 项目背景与核心需求在嵌入式系统开发中,快速精确的数据检索一直是个关键挑战。传统EEPROM虽然能可靠存储数据,但受限于串行接口和页写机制,在大数据量场景下往往成为性能瓶颈。而25CSM04这款Page EEPROM与STM32F207ZG高性能MCU的组合&…

2026/7/4 0:34:42 阅读更多 →
2026视频去水印教程手机电脑免费方法与软件推荐

2026视频去水印教程手机电脑免费方法与软件推荐

日常整理学习素材、收藏参考内容时,我们常会遇到带平台标识的视频,不同的水印位置、不同的使用场景,适合的处理方式也不一样。本文整理了 2026 年实用的手机、电脑端免费处理方法,搭配常用工具介绍与合规提示,适合个人…

2026/7/4 0:32:41 阅读更多 →
[线性代数]正定矩阵

[线性代数]正定矩阵

题型:已知正定矩阵,求参数取值范围。步骤1:写出$A kE$的矩阵已知$A \begin{bmatrix} 0 & 1 & 1 \\ 1 & 2 & 1 \\ 1 & 1 & 0 \end{bmatrix}$单位矩阵$E \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \…

2026/7/4 0:30:41 阅读更多 →
你的Windows个人管家:用Win11Debloat打造专属系统体验

你的Windows个人管家:用Win11Debloat打造专属系统体验

你的Windows个人管家:用Win11Debloat打造专属系统体验 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and cu…

2026/7/4 0:26:39 阅读更多 →
气候适配科技面料推荐程序,根据地域温湿度匹配透气保暖功能性服饰。

气候适配科技面料推荐程序,根据地域温湿度匹配透气保暖功能性服饰。

气候适配科技面料推荐程序 —— 地域温湿度 功能性服饰匹配一、实际应用场景描述在《时尚产业与品牌创新》课程中,功能性面料(Functional Fabrics) 是科技驱动品牌创新的核心赛道。全球气候变暖导致极端天气频发:- 2024 年夏季&a…

2026/7/4 0:22:37 阅读更多 →
明日方舟桌宠Ark-Pets:5分钟打造你的智能桌面伙伴

明日方舟桌宠Ark-Pets:5分钟打造你的智能桌面伙伴

明日方舟桌宠Ark-Pets:5分钟打造你的智能桌面伙伴 【免费下载链接】Ark-Pets Arknights Desktop Pets | 明日方舟桌宠 (ArkPets) 项目地址: https://gitcode.com/gh_mirrors/ar/Ark-Pets 还在寻找能让电脑桌面焕然一新的创意工具吗?Ark-Pets作为一…

2026/7/4 0:22:37 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻