spring – 异常在捕获后传播

前端之家收集整理的这篇文章主要介绍了spring – 异常在捕获后传播前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我发生了最奇怪的事情,我无法弄明白为什么.描述这个的最好方法是提供一个简单的例子:

@Service
@Transactional
public class Foo{
    public ModelAndView delete(@modelattribute("abc") Long id) {
        ModelAndView mav = new ModelAndView();
        try {
            getDaoService().delete(id); //Calls Bar.delete()
        } catch (final Exception e) {
            // Add a custom error message to the mav for the user to see
            mav.getModelMap().addAttribute(blah,blah);
        }
        return mav;
    }
}

@Service
@Transactional
public class Bar {
    public void delete(final E entity) throws HibernateException {
        if (null != entity) {
            try {
                sessionFactory.getCurrentSession().delete(entity);
            } finally {
                sessionFactory.getCurrentSession().flush();
            }
        }
    }
}

在这种特殊情况下,我试图删除一个具有约束违规的对象(ORA-02292).我希望删除失败,因为这个.当删除失败时,我希望向用户显示适当的自定义消息.

呼叫失败并显示以下内容,而不是向用户显示自定义消息:

org.springframework.transaction.UnexpectedRollbackException: Transaction
rolled back because it has been marked as rollback-only

当我使用调试器时,我可以看到错误被正确捕获,并且ModelAndView对象内部有自定义消息.所以,我不知道为什么在捕获和处理异常之后仍然会抛出异常.有谁有洞察为什么会这样?

最佳答案
在@Transactional注释中,您可以使用noRollbackForClassName属性声明是否由于给定异常而回滚事务.你可以这样做.

@Service
@Transactional(noRollbackForClassName = "java.lang.Exception")
public class YourClass {
    ...
}

但是,请注意,只是说noRollbackForClassName =“java.lang.Exception”意味着它不会为任何异常(或其子类)回滚,因此这不是一个好习惯.

你应该做的是,找出实际抛出的异常(可能是通过打印出e.getClass().getName()),然后将该类名设置为noRollbackForClassName值.

理由是,这种情况正在发生,因为如果在尝试delete()时抛出某个异常,则当前事务会自动标记为仅回滚,如果尝试提交,则会抛出您看到的异常.传递此方法方法是明确声明此特定异常不应导致回滚.

原文链接:https://www.f2er.com/spring/432814.html

猜你在找的Spring相关文章