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

查看:22
本文介绍了为什么事务在 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 都会触发回滚,任何已检查的异常都不会.

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.

这背后的基本原理是 RuntimeException 类通常被 Spring 用来表示不可恢复的错误条件.

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天全站免登陆