Java Spring 事务:在 Exception 或 Throwable 上回滚

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21188239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 07:11:48  来源:igfitidea点击:

Spring transaction: rollback on Exception or Throwable

javaspringtransactions

提问by Igor Konoplyanko

I wonder whether it makes sense to use instead of

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

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

to use Throwable

使用 Throwable

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

As I understand catching Errorwill help us behave correctly even when something really bad happen. Or maybe it wouldn't help?

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

采纳答案by René Link

As I understand catching Error will help us behave correctly even when something really bad happen. Or maybe it wouldn't help?

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

You don't need to explicitly specify rollbackFor = Throwable.class, because spring will by default rollback the transaction if an Erroroccurs.

您不需要显式指定rollbackFor = Throwable.class,因为如果Error发生,spring 默认会回滚事务。

See 12.5.3 Rolling back a declarative transaction

12.5.3 回滚声明性事务

In its default configuration, the Spring Framework's transaction infrastructure code only marks a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. (Errors will also - by default - result in a rollback). Checked exceptions that are thrown from a transactional method do not result in rollback in the default configuration.

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

Or take a look at the DefaultTransactionAttribute

或者看看 DefaultTransactionAttribute

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

回答by Sotirios Delimanolis

Since you are using @Transactional, we can safely assume you are doing your database operations through Spring, Hibernate, or other JDBC wrappers. These JDBC wrappers don't typically throw checked exceptions, they throw runtime exceptions that wrap the JDBC SQLExceptiontypes.

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

@Transactionalis setup to rollback, by default, only when an unchecked exception is thrown.

@Transactional默认情况下,设置为仅在引发未经检查的异常时回滚。

Consider a use case like so

考虑这样的用例

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

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

You wouldn't necessarily want to rollback the DB operation just because we couldn't write something to a file.

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

Similarly

相似地

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

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

You wouldn't necessarily want to rollback the saved entity just because some service cause too much memory to be consumed.

您不一定会因为某些服务导致消耗过多内存而回滚保存的实体。

@Transactionalgives you the option. Use it where appropriate.

@Transactional给你选择。在适当的地方使用它。

回答by Arsen Alexanyan

I don't know is it possible or not but handling Throwables like Errors is a bad style of programming, it is not the developers responsibility to handle this kind of fatal errors. There always can happen bad things which You cannot handle. You should handle checked exceptions if necessary, which are known to your system like some type of logical errors.

我不知道是否可能,但是Throwable像 s 这样处理sError是一种糟糕的编程风格,处理这种致命错误不是开发人员的责任。总是会发生你无法处理的坏事。如有必要,您应该处理已检查的异常,这些异常对于您的系统来说是已知的,例如某种类型的逻辑错误。

回答by Ali.Mojtehedy

Default value of rollback is register on Error Exception but when u register try{}catch{}manually it overriding the error, so in this case use

回滚的默认值是在错误异常上注册,但是当你try{}catch{}手动注册时它会覆盖错误,所以在这种情况下使用

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

to do it manually or remove try catch

手动执行或删除 try catch

also you may register exception type in transactional annotation such:

您也可以在事务注释中注册异常类型,例如:

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