@Transactional是Spring声明式事务核心注解,通过AOP代理在方法执行前后自动开启、提交或回滚事务;默认仅对RuntimeException回滚,传播行为为REQUIRED,需注意public方法、避免自调用、正确配置事务管理器等生效前提。

Spring 的 @Transactional 是实现声明式事务最常用、最简洁的方式,它把事务边界从代码逻辑中剥离出来,交由 Spring AOP 自动代理管理,开发者只需关注业务本身。
事务注解的基本用法
在 Service 层方法上添加 @Transactional,Spring 就会在方法执行前后自动开启、提交或回滚事务。最简单的写法是直接加注解:
- 标注在 public 方法上才生效(private/protected 方法不被代理)
- 默认只对 unchecked 异常(
RuntimeException及其子类)回滚,checked 异常(如Exception)不会触发回滚 - 事务传播行为默认是
REQUIRED:如果当前已有事务则加入,没有则新建一个
常见事务属性配置
通过注解参数可精细控制事务行为:
-
rollbackFor:指定哪些异常触发回滚,例如
@Transactional(rollbackFor = Exception.class) -
noRollbackFor:明确排除某些异常不回滚,比如
@Transactional(noRollbackFor = BusinessException.class) -
propagation:调整传播行为,如
REQUIRES_NEW强制新建事务(适合日志记录、补偿操作等独立场景) -
isolation:设置隔离级别,如
ISOLATION_READ_COMMITTED(注意:底层数据库需支持) - timeout:设置事务超时时间(单位秒),避免长时间占用数据库连接
-
readOnly:设为
true可提示数据库优化执行计划(如 MySQL 的 InnoDB 会跳过 undo log 写入)
事务失效的典型场景
看似加了注解,但事务没起作用?常见原因有:
立即学习“Java免费学习笔记(深入)”;
- 方法不是 public —— Spring 代理无法切入
- 自调用问题:同一个类内,A 方法调 B 方法(B 有
@Transactional),因代理对象未参与,事务不生效 - 未启用事务管理:忘记在配置类或 XML 中添加
@EnableTransactionManagement或<tx:annotation-driven/> - 数据源未配置事务管理器(如
DataSourceTransactionManager),或 Bean 名不是默认的transactionManager - 使用了不支持事务的数据库引擎(如 MySQL 的 MyISAM 表)
配合编程式事务灵活处理
声明式事务覆盖大多数场景,但遇到动态决定是否开启事务、嵌套复杂分支逻辑等情况,可结合 TransactionTemplate 或 PlatformTransactionManager 手动控制:
- 注入
TransactionTemplate,用execute()包裹需要事务保护的逻辑 - 适用于事务边界与方法边界不一致、或需在运行时判断是否开启事务的场景
- 注意手动管理时,异常处理和回滚需自行编码,不如声明式简洁安全
不复杂但容易忽略。关键是理解代理机制、异常类型与回滚规则、以及传播行为的实际影响,而不是堆砌注解。


















