spring事务生效需满足三个硬性前提:必须是spring管理的bean、调用走代理对象、数据源支持事务;配置上需确认@enabletransactionmanagement、数据源正确、事务管理器自动装配;常见误配包括private方法加注解、未托管类使用、捕获异常不抛出等。

事务注解生效的三个硬性前提
缺一不可,否则无论怎么配都白搭:
- 必须是 Spring 管理的 Bean:类上得有 @Service / @Repository / @Component 等 Spring 注解,普通 new 出来的对象无效;
- 调用必须走代理对象:即方法必须被 Spring AOP 代理拦截到——这意味着不能在同一个类里 self-call(内部直接调用),也不能用 private/protected/final 方法加 @Transactional;
- 数据源必须支持事务:比如 HikariCP + MySQL 的 JDBC 连接池,且数据库引擎是 InnoDB(MyISAM 不支持事务);
基础配置项(Spring Boot 场景)
不需要写 XML,但这几处必须确认或显式设置:
- @EnableTransactionManagement:Spring Boot 2.0+ 默认启用,但如果手动写了 @Configuration 类,建议显式加上;
- 数据源配置正确:application.yml 中确保 spring.datasource.url 包含 useSSL=false&serverTimezone=UTC(避免连接异常干扰事务);
- 事务管理器自动装配:Spring Boot 会根据 DataSource 自动创建 PlatformTransactionManager,一般无需手写@Bean,除非多数据源;
@Transactional 常见误配点(面试高频)
这些看似“配了”,实则等于没配:
- 加在 private 方法上 → 无效(代理无法拦截);
- 加在未被 Spring 托管的类上(比如工具类、DTO)→ 无效;
- 只捕获异常却没抛出 → 不回滚(默认只对 RuntimeException 及其子类回滚);
- 用了 try-catch 吞掉异常,又没手动 setRollbackOnly() → 事务提交;
- 传播行为写成 SUPPORTS 或 NOT_SUPPORTED → 实际无事务;
调试事务是否生效的实用办法
别靠猜,用日志验证:
- 开启事务日志:
logging.level.org.springframework.jdbc.support.JdbcTransactionManager=DEBUG; - 观察控制台是否输出 “Creating new transaction”、“Initiating transaction rollback” 等关键词;
- 配合数据库查看当前连接是否处于事务状态(如 MySQL 执行
SELECT TRX_ID, TRX_STATE FROM INFORMATION_SCHEMA.INNODB_TRX;);
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











