java Spring 交易:发生异常或可引发时回滚

cotxawn7  于 2023-02-15  发布在  Java
关注(0)|答案(4)|浏览(173)

我不知道用...代替...是否有意义

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

要使用Throwable

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

据我所知,捕捉Error将帮助我们正确地行为,即使当一些非常糟糕的事情发生。

weylhg0b

weylhg0b1#

据我所知,捕捉错误将帮助我们正确的行为,即使是在一些非常糟糕的事情发生。
您不需要显式地指定rollbackFor = Throwable.class,因为如果Error发生,spring将默认回滚事务。
请参见1.4.3.回滚声明性事务
在其默认配置中,Spring框架的事务基础设施代码只在运行时、未检查异常的情况下(即抛出的异常是RuntimeException的示例或子类时)才标记回滚事务。(默认情况下,错误示例导致回滚)。从事务方法引发的选中异常在默认配置中不会导致回滚。
或者看看DefaultTransactionAttribute

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

rwqw0loc2#

由于您使用的是@Transactional,我们可以放心地假设您正在通过Spring、Hibernate或其他JDBC Package 器执行数据库操作,这些JDBC Package 器通常不会抛出已检查异常,而是抛出 Package JDBC SQLException类型的运行时异常。
默认情况下,@Transactional设置为仅在抛出未检查异常时回滚。
请考虑这样一个用例

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

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

您不必仅仅因为无法向文件写入内容就回滚DB操作。
同样

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

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

您不一定要回滚已保存的实体,因为某些服务会消耗过多的内存。
@Transactional为您提供了选项。请在适当的地方使用它。

au9on6nz

au9on6nz3#

回滚的默认值是在错误异常时注册,但当您手动注册try{}catch{}时,它会覆盖错误,因此在本例中使用

catch {
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      }

手动执行或删除try catch
你也可以在事务注解中注册异常类型,例如:

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

mf98qq944#

我不知道这是可能的还是不可能的,但是像Error s那样处理Throwable s是一种糟糕的编程风格,处理这种致命错误不是开发人员的责任。总是会发生你无法处理的糟糕事情。如果必要的话,你应该处理检查异常,这是你的系统所知道的,就像某种类型的逻辑错误一样。

相关问题