为什么事务在RuntimeException上回滚而不在SQLException上回滚 [英] why does transaction roll back on RuntimeException but not SQLException

查看:910
本文介绍了为什么事务在RuntimeException上回滚而不在SQLException上回滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring管理的服务方法来管理数据库插入.它包含多个插入语句.

I have a Spring-managed service method to manage database inserts. It contains multiple insert statements.

@Transactional
public void insertObservation(ObservationWithData ob) throws SQLException 
{
    observationDao.insertObservation(ob.getObservation());
            // aop pointcut inserted here in unit test
    dataDao.insertData(ob.getData());
}

我有两个单元测试,它们在调用第二个插入之前引发异常.如果异常是RuntimeException,则事务将回滚.如果该异常是SQLException,则将保留第一个插入.

I have two unit tests which throw an exception before calling the second insert. If the exception is a RuntimeException, the transaction is rolled back. If the exception is a SQLException, the first insert is persisted.

我很困惑.谁能告诉我为什么事务不回滚到SQLException?谁能提出建议如何管理这个问题?我可以捕获SQLException并抛出RuntimeException,但这似乎很奇怪.

I'm baffled. Can anyone tell me why the transaction does not roll back on a SQLException? Can anyone offer a suggestion how to manage this? I could catch the SQLException and throw a RuntimeException, but that just seems weird.

推荐答案

这是定义的行为.来自文档:

This is defined behaviour. From the docs:

任何RuntimeException都会触发回滚,而任何已检查的Exception都不会触发.

Any RuntimeException triggers rollback, and any checked Exception does not.

这是所有Spring事务API的常见行为.默认情况下,如果在事务代码中抛出RuntimeException,则事务将回滚.如果引发了检查的异常(即不是RuntimeException),则该事务将不会回滚.

This is common behaviour across all Spring transaction APIs. By default, if a RuntimeException is thrown from within the transactional code, the transaction will be rolled back. If a checked exception (i.e. not a RuntimeException) is thrown, then the transaction will not be rolled back.

其基本原理是,Spring通常采用RuntimeException类来表示不可恢复的错误情况.

The rationale behind this is that RuntimeException classes are generally taken by Spring to denote unrecoverable error conditions.

如果愿意,可以从默认值更改此行为,但是如何执行此操作取决于您使用Spring API的方式以及设置事务管理器的方式.

This behaviour can be changed from the default, if you wish to do so, but how to do this depends on how you use the Spring API, and how you set up your transaction manager.

这篇关于为什么事务在RuntimeException上回滚而不在SQLException上回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆