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

自注入调用事务方法时异常未触发回滚的解决方案咨询

解决方案:修复事务不回滚问题

问题根源

你遇到的问题核心有两点:

  1. 内部调用导致事务代理失效:Spring事务基于动态代理实现,同一个类内部方法调用(比如c()直接调用a()、b())不会触发代理逻辑,a()和b()上的@Transactional注解完全不生效,所有操作都处于c()的事务上下文里。
  2. 检查异常不触发默认回滚:SQLException属于检查型异常,Spring默认的@Transactional仅对运行时异常(RuntimeException)和错误(Error)执行回滚,因此抛出该异常不会触发事务回滚,导致已执行的修改被提交。

方案一:调整事务回滚规则(快速解决)

直接修改c()的@Transactional注解,指定回滚的异常类型包含SQLException,确保异常触发时整个事务回滚:

@Transactional(rollbackFor = SQLException.class)
void c() {
  serviceClass.a();
  serviceClass.b();
}

注:此方案未解决内部代理失效问题,a()和b()的事务注解仍不生效,所有操作共用c()的事务。


方案二:修复内部调用的代理失效问题(彻底解决独立事务需求)

若需要a()和b()各自生效独立事务,需让调用走代理逻辑,有两种常用方式:

方式1:获取自身代理对象调用

在类中注入ApplicationContext,初始化时获取当前类的代理实例,用代理对象调用方法:

@Service
public class YourService {
  @Autowired
  private ApplicationContext context;
  private YourService selfProxy;

  @PostConstruct
  public void init() {
    // 获取自身代理实例
    selfProxy = context.getBean(YourService.class);
  }

  @Transactional
  public void a() {
    // 业务逻辑
  }

  @Transactional(rollbackFor = SQLException.class)
  public void b() throws SQLException {
    throw new SQLException();
  }

  @Transactional
  public void c() {
    // 通过代理调用,触发事务注解逻辑
    selfProxy.a();
    selfProxy.b();
  }
}

方式2:拆分服务类(推荐,符合单一职责)

将a()和b()拆分到不同的Service类中,跨类调用会自动走代理,事务注解正常生效:

@Service
public class AService {
  @Transactional
  public void a() {
    // 业务逻辑
  }
}

@Service
public class BService {
  @Transactional(rollbackFor = SQLException.class)
  public void b() throws SQLException {
    throw new SQLException();
  }
}

@Service
public class CService {
  @Autowired
  private AService aService;
  @Autowired
  private BService bService;

  @Transactional
  public void c() {
    aService.a();
    bService.b();
  }
}

方案三:使用AspectJ编织事务(特殊场景可选)

若必须保留类内部调用且生效事务,可开启AspectJ编译/运行时编织,替代Spring动态代理。需在配置类添加:

@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)

并引入AspectJ相关依赖。此方式复杂度较高,仅适合有特殊需求的场景,不推荐常规业务使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:17:56