【问题标题】:Spring nested transaction rollback after handling exception处理异常后的Spring嵌套事务​​回滚
【发布时间】:2018-01-26 13:22:08
【问题描述】:

我有一个@Service 类,它有一个@Transactional 方法,该方法在另一个服务上调用另一个@Transactional 方法。类似的东西:

@Service
public class AService {
  @Autowired
  BService b;
  @Autowired
  ARepository aRepo;

  @Transactional
  public void methodOne(){
    try{
      b.methodTwo();
    }catch(RuntimeException e){}
    aRepo.save(new A());
  }

} 

@Service
public class BService{

    @Transactional
    public void methodTwo(){
      if(true)
        throw new RuntimeException();
    }

}

我希望 A 实体将被插入,但如果任何嵌套事务抛出异常,即使此异常在 AService.methodOne() 处处理,插入也会拒绝。

我可以用@Transactional(propagation = Propagation.REQUIRES_NEW) 注释methodTwo()。但它会超越性能。

【问题讨论】:

  • 没有嵌套事务只有一个。如果你想要单独的事务,你需要用REQUIRES_NEW 注释另一个事务。是的,这是一个性能影响,因为它开始一个新的 tx。
  • 这个案例还有其他更优雅的解决方案吗?
  • 没有。您要么提交所有内容,要么回滚所有内容......您不能部分提交会超过事务 ACID 属性的内容。
  • 如果我将 try-catch 块移动到 methodTwo() 实体插入成功。但是在我真正的方法中,我有很多方法调用,其中一些是业务逻辑所必需的。

标签: java spring transactions nested-transactions


【解决方案1】:

如果您不想在methodTwo 发生异常后从methodOne 回滚您的事务,您可以使用@Transactional(noRollbackFor = {RuntimeException.class}) 添加注释methodOne。但请注意,这有点滑坡,如果您真的想这样做,请三思而后行。

【讨论】:

  • methodOne() 有很多其他的服务方法调用,而且这些方法调用的不仅仅是AService。我希望这种行为只在 AService 中。
猜你喜欢
  • 1970-01-01
  • 2021-04-25
  • 2018-08-09
  • 1970-01-01
  • 2022-07-22
  • 2012-08-20
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多