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

Spring Boot @Transactional事务未回滚问题求助

事务未回滚问题的排查与修复方案

嘿,这问题我碰到过好多次——明明加了@Transactional,抛了异常却留着第一个实体,太闹心了!我帮你梳理几个最可能的原因,一步步排查:

1. 最常见的坑:异常被悄悄吞掉了

如果你的cadastraProduto方法里,调用第二个实体保存(比如importSkuService的方法)时用了try-catch,但只打了日志没重新抛出异常,Spring的事务拦截器根本感知不到异常,当然不会触发回滚!

比如这种错误写法:

try {
    importSkuService.save(sku); // 这里抛出DuplicateEntityException
} catch (DuplicateEntityException e) {
    log.error("SKU重复了", e);
    // 没重新抛出,事务就认为一切正常
}

修复:要么删掉try-catch让异常直接往上抛,要么在catch块里重新抛出:throw e;(或者包装成RuntimeException,比如throw new RuntimeException("保存SKU失败", e);)。

2. 事务注解根本没生效

Spring事务是靠动态代理实现的,这几个情况会导致注解失效:

  • 内部方法调用:如果是同一个类里的非事务方法调用了这个带@Transactional的cadastraProduto方法,代理不会生效,事务等于白加。
  • 方法不是public:Spring事务注解只对public方法生效,private/protected方法上的注解会被直接忽略。

3. 事务管理器配置有问题

如果你的项目有多数据源,要确认@Transactional指定了正确的事务管理器,比如:

@Transactional(transactionManager = "produtoTxManager", rollbackFor = {DuplicateEntityException.class, Exception.class})

另外,检查DuplicateEntityException是不是Checked Exception?不过你已经把它加到rollbackFor里了,这条重点看多数据源场景。

4. 保存操作没加入当前事务

确保importProdutoRepository是Spring Data JPA的接口(或者被Spring正确托管),如果是自己手写的JDBC操作,有没有手动获取事务连接?要是绕开了Spring的事务管理,保存操作就不会受@Transactional控制。

快速验证小妙招

在cadastraProduto方法开头加一行代码,看看事务到底开没开:

System.out.println("当前是否有活跃事务:" + TransactionSynchronizationManager.isActualTransactionActive());

如果输出false,那肯定是事务没生效,回到前面的代理问题排查。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:17:59