我有一个 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/