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

标注@Transactional的方法执行逻辑是什么?为何需要创建代理?

Spring @Transactional注解核心问题解答

1. 标注@Transactional的方法执行时具体会发生什么?

注意只有标注在public方法、且由代理对象触发调用的情况下,事务逻辑才会执行,同类内部调用、private方法标注注解都会失效
当符合生效条件的@Transactional方法被调用时,完整流程如下:

  • 调用实际走到Spring为目标类生成的AOP代理对象的对应方法,不会直接执行原类的业务逻辑
  • 代理逻辑先读取注解上的配置参数,包括传播行为、隔离级别、超时时间、回滚异常类型、不回滚异常类型等
  • 调用配置的事务管理器,根据传播规则判断是否需要新建事务:如果当前线程已经绑定了符合要求的事务,就直接复用该事务对应的数据库连接;否则新建一个事务,同时将新的数据库连接绑定到当前线程
  • 执行开发者编写的目标业务方法
  • 方法执行完成后根据执行结果做事务收尾:如果方法抛出了符合回滚规则的异常(默认仅对RuntimeException和Error触发回滚),就执行事务回滚;其余情况都会执行事务提交
  • 最后解除当前线程和数据库连接的绑定,归还连接到连接池,事务生命周期结束

2. @Transactional是不是仅在方法包含数据库操作时才会生效?

不是。
只要注解符合上述生效条件,不管方法内部有没有数据库操作,事务的完整控制流程都会正常执行:

  • 哪怕方法是空实现,代理也会正常走获取数据库连接、开启事务、提交事务的流程,只是没有执行具体SQL而已,这种情况会无意义占用数据库连接资源,带来不必要的性能开销
  • 如果方法内部只有非数据库操作(比如Redis、本地内存计算等),@Transactional也会正常启动数据库事务,但对非数据库操作没有任何事务控制能力,属于无效配置

3. 创建代理的必要性是什么?

@Transactional属于声明式事务,核心是在不修改原有业务代码的前提下,给业务方法增加事务控制的增强逻辑,这一能力依赖Spring AOP实现,代理是Spring AOP的核心载体:

  • 没有代理的情况下,直接调用原类的方法无法插入事务开启、提交、回滚的额外逻辑,也就无法实现声明式事务的无侵入特性
  • Spring会根据目标类是否实现接口,自动选择JDK动态代理或CGLIB代理生成代理对象,两类代理的核心作用都是承载事务增强逻辑
  • 我们常遇到的同类非事务方法调用事务方法不生效的问题,本质就是同类内调用走的是原类this对象,不是代理对象,无法触发代理层的事务增强逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:24:03