事务失效的几种情况以及是为什么(详解)

一.Aop失效因为事务就是通过aop来实现的

Spring 先动态生成一个子类,继承你要拦截的那个类(比如 UserService)

  • 在这个子类里重写目标方法(比如 addUser)
  • 重写的方法里面,直接去调用你写的 @Aspect 切面里的 around 方法
  • 切面的 around 里先做前置逻辑(开启事务)
  • 再通过 proceed() 调用原来的父类方法(被拦截的那个方法)
  • 最后做后置逻辑(提交 / 回滚)

AOP 基于动态代理实现,只有调用【代理对象】的方法,才会走切面的前置 → joinPoint.proceed () → 后置流程,增强才生效

1. 方法被 private 修饰(失效)

  • private 方法只能在当前类内部访问,代理对象通过反射 / 继承都调用不到这个方法
  • 代理进不去,切面流程走不起来,proceed() 根本触发不了
  • 最终:事务、AOP 增强直接失效
  • 也就是joint.proceed方法无法调用。(第四部无法完成)

2. 方法被 final /static 修饰(失效)

  • final 方法:不能被代理类重写,代理没法给方法套增强逻辑(也就是第二步没有办法完成)
  • static 方法:属于类,不属于对象实例,代理管不了静态方法
  • 结果:代理无法增强,proceed() 不执行,AOP 失效。

3. 类没有被 Spring 管理(没加 @Service/@Component 等)(失效)

  • 类没交给 Spring 管理,就不会被放进 IOC 的 Map 容器
  • Spring 不会为它生成代理对象
  • 连代理都没有,自然没有切面流程,proceed() 不存在
  • 结果:AOP 完全不生效
  • 也就是无法被继承(第一步无法完成)

4. 类内部自调用(this. 方法 ())(最经典失效)

  1. 外部调用 → 走代理对象,执行 AOP 前置逻辑
  2. 执行 joinPoint.proceed() → 进入原始目标对象(this)
  3. 原始对象里自调用方法,此时代理对象已经不存在了
  4. 自调用不走代理,第二次的 AOP 拦截完全失效
  5. 被调用方法的增强逻辑全部丢失

这个具体就是:

1. this 到底是谁?

  • 外部调用方法时,用的是Spring 生成的代理子类对象 ,此时 this = 代理对象
  • 执行 proceed() 调用父类(原类)的原方法后→ 原方法里的 this 直接变成了【原类对象(父类)】,不再是代理子类对象!

2. 父类(原类)根本调用不到子类(代理)的重写方法

  • 子类能重写父类方法,但父类永远看不到、调用不到子类的方法
  • 原类内部自己调用自己的方法(自调),比如 this.methodB()→ 这个 this 是原类对象,只能调用原类自己的原生 methodB→ 完全绕开了代理子类重写的、带 AOP 切面的方法

3. 最终结果

AOP 切面没被执行,事务、日志等增强逻辑直接失效

二、非aop的情况

  • 数据库引擎本身不支持事务MySQL 的 MyISAM 引擎就没有事务功能,不管你 Spring 事务怎么写、代理正不正常,都不可能回滚。只有 InnoDB 引擎才支持事务。

  • 异常被自己 try-catch 吃掉了,没抛出去 Spring 事务是靠捕获异常来触发回滚的。你在事务方法里把异常 catch 住,又不往外抛,Spring 根本不知道出错了,就不会回滚。

  • 抛出的异常不是 Spring 默认回滚的类型 Spring 事务默认只回滚 RuntimeException(运行时异常)和 Error 。像 IOExceptionSQLException 这种编译期受检异常 ,默认不会触发回滚,必须手动加:@Transactional(rollbackFor = Exception.class)

  • 事务传播行为配置错了比如把传播级别写成:

    • NOT_SUPPORTED:不支持事务,已存在的事务也挂起
    • NEVER:绝不允许有事务,有就抛异常事务根本不会开启,自然失效。
  • 多线程里调用事务方法 Spring 事务是和当前线程绑定的。新开线程去调用事务方法,新线程拿不到原来的事务,也走不到事务上下文,事务直接失效。

  • 没有开启事务注解驱动 老式 Spring 项目需要手动加 @EnableTransactionManagement 才能让 @Transactional 生效,没加的话注解等于白写。

相关推荐
武藤一雄2 小时前
C#:nameof 运算符全指南
开发语言·microsoft·c#·.net·.netcore
wertyuytrewm3 小时前
Java面试——Java基础
java·jvm·面试
czlczl200209253 小时前
RAG实现思路流程
java·jvm
带娃的IT创业者3 小时前
WeClaw_40_系统监控与日志体系:多层次日志架构与Trace追踪
java·开发语言·python·架构·系统监控·日志系统·链路追踪
Y001112363 小时前
JDBC原理
java·开发语言·数据库·jdbc
程序员侠客行3 小时前
Tomcat 从陌生到熟悉
java·tomcat·web
wertyuytrewm3 小时前
Java 异常|Java Exceptions
java·开发语言
ProgramHelpOa3 小时前
Amazon SDE Intern OA 2026 最新复盘|70分钟两题 Medium-Hard
java·前端·javascript
雪碧聊技术3 小时前
深入理解 Java GC:从“房间清洁工”到解决系统卡顿实战
java·开发语言