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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:25:13