Spring Boot服务层事务未生效,异常时无法回滚求助
Spring Boot服务层事务不生效问题排查与解决
核心原因:同一类内部方法调用导致事务失效
Spring的事务是基于AOP代理实现的,你在非事务方法insertEmployee里直接调用同一类中带@Transactional的insertEmployee1,这种内部调用不会经过Spring的代理对象,导致事务注解完全不生效。
解决办法
办法1:通过自身代理对象调用事务方法
在Service类中注入自身的代理实例,用这个代理对象触发事务方法:
@Service public class EmpService { @Autowired EmployeeDao employeeDao; @Autowired EmployeeRepo empRepo; @Autowired EmployeeHealthInsuranceRepo healthRepo; @Autowired private EmpService empService; // 注入自身的代理对象 @Transactional public void insertEmployee1(Employee employee,EmployeeHealthInsurance employeeHealthInsurance) { empRepo.save(employee); System.out.println(100/0); healthRepo.save(employeeHealthInsurance); } public void insertEmployee(Employee employee,EmployeeHealthInsurance employeeHealthInsurance) { empService.insertEmployee1(employee,employeeHealthInsurance); // 通过代理对象调用事务方法 } }
办法2:将事务方法抽离到单独的Service类
把带@Transactional的方法移到独立的Service组件中,通过依赖注入调用,确保走AOP代理逻辑:
// 新建事务处理专用Service @Service public class EmpTransactionService { @Autowired EmployeeRepo empRepo; @Autowired EmployeeHealthInsuranceRepo healthRepo; @Transactional public void insertEmployee1(Employee employee,EmployeeHealthInsurance employeeHealthInsurance) { empRepo.save(employee); System.out.println(100/0); healthRepo.save(employeeHealthInsurance); } } // 原Service类 @Service public class EmpService { @Autowired EmployeeDao employeeDao; @Autowired EmpTransactionService empTransactionService; public void insertEmployee(Employee employee,EmployeeHealthInsurance employeeHealthInsurance) { empTransactionService.insertEmployee1(employee,employeeHealthInsurance); } }
办法3:使用AspectJ织入事务(不推荐常规场景)
如果不想调整代码结构,可以通过AspectJ的编译时或加载时织入实现事务,但配置复杂,普通Spring Boot项目一般不需要这种方式。
额外检查点
- 确认启动类上添加了
@EnableTransactionManagement注解(Spring Boot 2.x+默认自动配置,但显式添加更稳妥)。 @Transactional默认仅对RuntimeException和Error触发回滚,你代码中100/0抛出的ArithmeticException属于RuntimeException,没问题;如果是检查型异常,需要手动指定rollbackFor属性,比如@Transactional(rollbackFor = Exception.class)。
内容的提问来源于stack exchange,提问作者Admin Metaversity
相关产品推荐
相关产品推荐

