【问题标题】:Does Specifying @Transactional rollbackFor Also Include RuntimeException是否指定 @Transactional rollbackFor 还包括 RuntimeException
【发布时间】:2012-10-01 13:47:44
【问题描述】:
@Transactional(rollbackFor = MyCheckedException.class)
public void foo() {
    throw new RuntimeException();    
}

这个事务会被回滚,还是我也需要在注解中包含 RuntimeException.class?

【问题讨论】:

    标签: java spring exception transactions rollback


    【解决方案1】:

    无需在rollbackFor 列表中包含RuntimeException。即使您不提及它,它也会处理。

    我已经为 jdbcTemplate 尝试过:-

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = MyException.class)
    public void updateSalary(final int increment){
        jdbcTemplate.update("update EMPLOYEE set emp_salary = emp_salary + ?", increment);
        throw new RuntimeException("update exception");
    }
    
    输出: 插入后: 1 迪帕克 35000 2 约格什 35000 3 阿迪亚 35000 更新异常 更新后 1 迪帕克 35000 2 约格什 35000 3 阿迪亚 35000

    【讨论】:

    • @AlexBeardsley thnx 指出错误...我修改了答案..我重新运行了代码..是的,您不需要在 rollbackFor 列表中包含运行时异常。
    【解决方案2】:

    但是,请注意 Spring Framework 的事务 默认情况下,基础设施代码将只标记交易 在运行时回滚,未经检查的异常;也就是说,当 抛出的异常是 RuntimeException 的实例或子类。 (错误也会 - 默认情况下 - 导致回滚。)选中 不会导致从事务方法抛出的异常 在正在回滚的事务中。

    Source

    【讨论】:

    • 这仍然不能解释 rollbackFor 是附加的还是替换 RuntimeException/Error 上的默认行为。
    【解决方案3】:

    所以它也可以使用 CheckedException 回滚(默认为 RuntimeException),例如:

    @Transactional(rollbackFor = Exception.class)
    public void save(Book book) throws Exception {
        bookRepository.save(book);
        System.out.println("Saved in transcation.");
        // No data is persisted
        if (true) {
            throw new Exception();
        }
    }
    

    【讨论】:

    • @AkshayKasar 如果我不尝试,我就不会发帖。
    • 根据我的经验,当你这样做时,人们开始复制你的代码而不了解它是如何工作的,然后由于你不知道他们关于回滚/异常处理的真正意图,因此很难审查他们的代码.所以我更喜欢只在rollbackFor 中列出检查的异常。在大多数情况下,这与您的throws 声明中的内容相同,因此维护起来并不难。同样,在大多数情况下,我会避免使用throws Exception,因为无法判断实际抛出了哪些已检查异常。
    猜你喜欢
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多