简体   繁体   English

Spring事务:在Exception或Throwable上回滚

[英]Spring transaction: rollback on Exception or Throwable

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 Error will help us behave correctly even when something really bad happen. 据我所知,捕捉Error将帮助我们正确行事,即使发生了非常糟糕的事情。 Or maybe it wouldn't help? 或者也许没有用?

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 Error occurs. 您不需要显式指定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; 在其默认配置中,Spring Framework的事务基础结构代码仅在运行时未经检查的异常情况下标记用于回滚的事务; that is, when the thrown exception is an instance or subclass of RuntimeException. 也就是说,抛出的异常是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. 从事务方法抛出的已检查异常不会导致在默认配置中回滚。

Or take a look at the DefaultTransactionAttribute 或者看一下DefaultTransactionAttribute

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

Since you are using @Transactional , we can safely assume you are doing your database operations through Spring, Hibernate, or other JDBC wrappers. 由于您使用的是@Transactional ,我们可以放心地假设您正在通过Spring,Hibernate或其他JDBC包装器执行数据库操作。 These JDBC wrappers don't typically throw checked exceptions, they throw runtime exceptions that wrap the JDBC SQLException types. 这些JDBC包装器通常不会抛出已检查的异常,它们会抛出包含JDBC SQLException类型的运行时异常。

@Transactional is 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. 您不一定要回滚已保存的实体,因为某些服务会导致消耗太多内存。

@Transactional gives you the option. @Transactional为您提供选项。 Use it where appropriate. 在适当的地方使用它。

I don't know is it possible or not but handling Throwable s like Error s is a bad style of programming, it is not the developers responsibility to handle this kind of fatal errors. 我不知道是否可能但是处理像Error s这样的Throwable是一种糟糕的编程风格,开发人员不负责处理这种致命的错误。 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. 您应该在必要时处理已检查的异常,这些异常是您的系统已知的某种类型的逻辑错误。

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 rollback的默认值是在Error Exception上注册但是当你注册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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM