首页 > 解决方案 > 从事务回滚中排除私有方法执行

问题描述

我的项目中有一个服务方法,可以这样简化:

@Transactional
public void myTransactionalMethod(){
    try {
        soSomethingAndSaveOnDB(); // private method
    }catch (Exception exception){
        saveSomethingOnDBWhenAnErrorOccurs(); // private method
        throw exception;
    }
}

该方法是事务性的,并且正在执行一些可能导致抛出异常的主要逻辑。如果出现这种情况,则必须将保存在数据库中的任何数据恢复到以前的状态。

但是我还需要在一个catch块中处理抛出的异常,并在数据库中写入一些额外的数据来跟踪错误。

throw exception我的实现的问题是导致事务回滚并阻止创建与错误跟踪相关的数据的最终指令。

我想在这种情况下“禁用”事务回滚,以便在我的数据库中正确记录错误。

注意我重新抛出异常以将其传播到控制器并将其转换为 HTTP 错误。

哪一个可以很好地解决这个问题,保持soSomethingAndSaveOnDB()saveSomethingOnDBWhenAnErrorOccurs()方法private

标签: javaspringspring-bootspring-transactions

解决方案


这似乎是一种解决方法而不是解决方案,但目前是我按照评论中的建议找到的最佳方法。

我这样修改了我的方法:

@Transactional(noRollbackFor = { ExceptionWrapper.class })
public void myTransactionalMethod(){
    try {
        soSomethingAndSaveOnDB(); // private method
    }catch (Exception exception){
        saveSomethingOnDBWhenAnErrorOccurs(); // private method
        throw new ExceptionWrpper(exception);
    }
}

然后我定义了一个这样的类:

public class ExceptionWrapper extends RuntimeException {
    private final RuntimeException wrappedThrowable;
}

最后在我的控制器中,我以这种方式捕获了新的异常类型:

try {
    myTransactionalMethod();
}catch(ExceptionWrapper ew){
    throw ew.getWrappedThrowable();
}

推荐阅读