You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring事务疑问:add()不回滚add2()正常回滚的原因咨询

问题原因解释

核心原因是Spring事务基于动态代理实现,内部方法调用不会触发事务切面,具体拆解如下:

  • 调用add()方法时:

    • add()本身没有@Transactional注解,请求进来后直接执行原始对象的add()方法。
    • 调用this.transactionalError()属于同一类内部方法调用,完全绕过了Spring生成的事务代理对象,所以transactionalError()上的@Transactional注解根本不会被Spring的事务切面识别。
    • 这就导致myService.save(myObj)执行后直接提交到数据库,后续抛出的异常无法触发回滚,最终myObj留在数据库中。
  • 调用add2()方法时:

    • add2()带有@Transactional注解,请求进来时,Spring会通过代理对象执行add2()方法,此时事务已经被正常开启。
    • 虽然add2()内部调用transactionalError()还是内部调用,但整个add2()方法已经处于事务上下文之中,所以transactionalError()里的所有数据库操作都属于当前事务的一部分。
    • 当"".substring(2)抛出异常时,Spring会触发事务回滚,myObj和myObj2都不会被存入数据库,符合预期。

简单总结:Spring事务注解只有在通过代理对象调用方法时才会生效,同一类内的直接方法调用不会触发代理逻辑,自然无法启用事务。

内容的提问来源于stack exchange,提问作者Chouch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 01:20:09