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

SpringBoot Web项目中@Transactional不生效无法回滚问题求助

SpringBoot @Transactional 事务不回滚问题解决

你的代码里事务不生效的核心原因是同一个类内部的方法调用无法触发Spring的事务代理。Spring的@Transactional基于动态代理实现,只有通过代理对象调用方法时,事务切面才会生效。你在PlanServiceImpl的saveOrUpdatePlanBatch方法里直接调用本类的saveOrUpdateDailyPlan,属于内部调用,绕过了代理,导致注解完全失效。

解决方案

方案1:将事务方法抽取到独立Service类

把带@Transactional的方法移到新的Service中,通过注入的方式调用,触发代理逻辑:

@Service
public class DailyPlanService {
    @Autowired
    private ProductPlanOutputMainService productPlanOutputMainService;

    @Transactional(rollbackFor = Exception.class)
    public R saveOrUpdateDailyPlan(ProductPlanOutputMain productPlanOutputMain){
        productPlanOutputMainService.saveOrUpdatePlan(productPlanOutputMain);
        throw new RuntimeException("something wrong");
    }
}

@Service
public class PlanServiceImpl implements PlanService {
    @Autowired
    private DailyPlanService dailyPlanService;
    
    @Override
    public R saveOrUpdatePlanBatch(ProductPlanOutputMain productPlanOutputMain) {
        return dailyPlanService.saveOrUpdateDailyPlan(productPlanOutputMain);
    }
}

方案2:通过代理对象调用自身方法

开启代理暴露配置,用AopContext获取代理对象后调用事务方法:

  1. 在启动类/配置类添加注解:
@EnableAspectJAutoProxy(exposeProxy = true)
@SpringBootApplication
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}
  1. 修改PlanServiceImpl代码:
@Service
public class PlanServiceImpl implements PlanService {
    
    @Override
    public R saveOrUpdatePlanBatch(ProductPlanOutputMain productPlanOutputMain) {
        PlanServiceImpl proxy = (PlanServiceImpl) AopContext.currentProxy();
        return proxy.saveOrUpdateDailyPlan(productPlanOutputMain);
    }

    @Transactional(rollbackFor = Exception.class)
    public R saveOrUpdateDailyPlan(ProductPlanOutputMain productPlanOutputMain){
        productPlanOutputMainService.saveOrUpdatePlan(productPlanOutputMain);
        throw new RuntimeException("something wrong");
    }
}

方案3:调整调用结构(业务允许时)

直接让Controller调用带事务注解的方法,跳过内部调用:

@PostMapping(value = "/savePlan")
public R saveYearPlan(@RequestBody ProductPlanOutputMain productPlanOutputMain){
    return planService.saveOrUpdateDailyPlan(productPlanOutputMain);
}

基础检查项

  • 确认数据库支持事务(如MySQL需用InnoDB引擎,MyISAM不支持)
  • 确认SpringBoot已自动配置事务管理器(引入对应持久化依赖时会自动配置)

内容的提问来源于stack exchange,提问作者Nicholas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:53:08