春季事务:异常或可抛出时回滚

2022-09-01 12:46:15

我想知道使用而不是使用是否有意义

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)

使用Throwable

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)

据我所知,即使发生了非常糟糕的事情,捕捉也会帮助我们正确行事。或者也许它无济于事?Error


答案 1

据我所知,捕获错误将帮助我们正确行为,即使发生了非常糟糕的事情。或者也许它无济于事?

您不需要显式指定 ,因为默认情况下,如果发生 ,spring 将回滚事务。rollbackFor = Throwable.classError

请参阅 12.5.3 回滚声明性事务

在其默认配置中,Spring框架的事务基础结构代码仅在运行时未检查异常的情况下标记要回滚的事务;也就是说,当引发的异常是 RuntimeException 的实例或子类时。(默认情况下,错误也会导致回滚))。从事务方法引发的已检查异常不会导致默认配置中的回滚。

或者查看默认事务属性

public boolean rollbackOn(Throwable ex) {
    return (ex instanceof RuntimeException || ex instanceof Error);
}

答案 2

由于您正在使用 ,我们可以安全地假设您正在通过Spring,Hibernate或其他JDBC包装器执行数据库操作。这些 JDBC 包装器通常不会引发已检查的异常,它们会引发包装 JDBC 类型的运行时异常。@TransactionalSQLException

@Transactional设置为仅在需要时引发未选中的异常时才回滚。

考虑这样的用例

@Transactional
public void persistAndWrite(Bean someBean) throws IOException {
    // DB operation
    getSession().save(someBean); 

    // File IO operation which throws IOException
    someFileService.writeToFile(someBean); 
}

您不一定仅仅因为我们无法向文件写入某些内容而回滚数据库操作。

同样地

@Transactional
public void persistAndThrowOutOfMemory(Bean someBean)  {
    // DB operation
    getSession().save(someBean);

    // consumes all memory, throws OutOfMemoryError
    someService.hugeOperationThrowsOutOfMemoryError(); 
}

您不一定希望回滚保存的实体,因为某些服务导致消耗了太多内存。

@Transactional为您提供选项。在适当的情况下使用它。


推荐