@transactional加在方法上最常用且精准,仅对public方法生效;加在类上则为所有public方法统一启用事务,方法级配置优先级高于类级。

@Transactional 可以加在类上,也可以加在方法上,但作用范围和优先级不同,实际效果取决于 Spring 的代理机制和事务传播行为。
加在方法上:最常用、最精准的用法
直接标注在 public 方法上,表示该方法执行时启用事务管理。Spring 会为这个方法创建事务上下文,发生未捕获的运行时异常(RuntimeException 或其子类)或 Error 时自动回滚。
- 只能用于 public 方法(private、protected、package-private 无效,因为 Spring AOP 代理不拦截)
- 同一类中方法 A 调用本类的 @Transactional 方法 B,事务不会生效(内部调用绕过代理)
- 可指定
propagation、isolation、rollbackFor、noRollbackFor等属性
示例:
@Service<br>public class UserService {<br> @Transactional(rollbackFor = Exception.class)<br> public void createUser(User user) {<br> userDao.insert(user);<br> logDao.insert("create user"); // 若此处抛异常,上面 insert 也会回滚<br> }<br>}
加在类上:为所有 public 方法统一启用事务
标注在类上时,相当于为该类中所有 public 方法隐式加上 @Transactional(前提是这些方法没被显式覆盖)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 适用于整个服务类绝大多数操作都需要事务的场景,减少重复标注
- 类上的配置是默认值,方法上如果也加了
@Transactional,则方法级配置会覆盖类级配置(例如传播行为、只读标识等) - 仍受代理限制:仅对通过 Spring 容器注入调用的方法生效
示例:
@Service<br>@Transactional(rollbackFor = Exception.class, readOnly = true)<br>public class OrderQueryService {<br> public Order getOrderById(Long id) { ... } // 自动继承类级事务配置<br><br> @Transactional(readOnly = false) // 覆盖类级 readOnly=true<br> public void updateOrderStatus(Long id, String status) { ... }<br>}
注意:加在类上 ≠ 所有方法都事务化
以下情况事务不会生效,无论注解加在类还是方法上:
- 方法不是 public(Spring CGLIB 或 JDK 动态代理均不支持)
- 没有通过 Spring 容器获取 Bean(比如 new 出来的对象调用)
- 自调用(this.methodB()),因未走代理对象
- 异常被 try-catch 吞掉且未重新抛出
- 抛出的是受检异常(checked exception),而未在
rollbackFor中声明
底层依赖:代理模式决定是否生效
Spring 默认使用 JDK 动态代理(接口)或 CGLIB(类)生成代理对象。只有通过代理对象调用目标方法,@Transactional 才能被拦截并开启事务。
- 确保 Bean 是由 Spring 容器管理(用
@Service/@Repository等声明,并正确注入) - 避免在非 Spring 上下文中手动 new 对象或使用
new ClassX()调用 - 若需自调用事务生效,可通过
AopContext.currentProxy()强制走代理(需开启expose-proxy="true")
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










