spring - 为什么事务会在 RuntimeException 而不是 SQLException 上回滚

标签 spring transactions

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

@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,则保留第一个插入。

我很困惑。谁能告诉我为什么事务不会在 SQLException 上回滚?任何人都可以提供如何管理这个的建议吗?我可以捕获 SQLException 并抛出 RuntimeException,但这看起来很奇怪。

最佳答案

这是定义的行为。来自 docs :

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

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

这背后的基本原理是 Spring 通常采用 RuntimeException 类来表示不可恢复的错误情况。

如果您愿意,可以从默认值更改此行为,但如何更改取决于您如何使用 Spring API 以及如何设置事务管理器。

关于spring - 为什么事务会在 RuntimeException 而不是 SQLException 上回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7125837/

相关文章:

java - 我应该将哪个版本的 Spring Security 与 spring core 3.2.5.RELEASE 一起使用

java - EclipseLink:检查当前事务隔离级别

java - 如何从事务方法调用非事务方法

java - 为 secure spring petclinic 的每个用户单独的 mysql 登录

Java EE 服务器中的 Spring Batch

java - Spring JPA 无法在一个线程中正确处理多个事务

php - 交易期间 key '...' 的重复条目 'PRIMARY'

c++ - MFC/C++有数据库事务机制吗?

spring - Spring Retry 中异常表达式的使用

spring - ThymeLeaf - 将表数据(ArrayList)发布到另一个 Controller