Grails下如何防止异常导致事务回滚?

     2023-05-07     192

关键词:

【中文标题】Grails下如何防止异常导致事务回滚?【英文标题】:How do I prevent exceptions from causing a transaction rollback under Grails? 【发布时间】:2013-03-27 06:19:21 【问题描述】:

我的 Grails 服务存在一个问题,即与事务无关的吞下异常导致事务回滚,即使它与域对象的持久性无关。

在我的服务中,我有一些类似的东西

updateSomething(domainObj) 
    def oldFilename = domainObj.filename
    def newFilename = getNewFilename()

    domainObj.filename = newFilename
    domainObj.save(flush: true)

    try 
        cleanUpOldFile(oldFilename)
     catch (cleanupException) 
        // oh well, log and swallow
    

我看到的是,当我在清理旧文件时遇到异常时,我会记录并吞下它,但它仍然会导致事务回滚,即使我已经完成了域对象的更新。

如何限制范围事务在清理之前完成,或者是否有其他方法可以让清理异常不导致回滚?

为了记录,我使用的是 Grails 2.1.1

【问题讨论】:

这个问题会导致“org.hibernate.LazyInitializationException: could not initialize proxy - no Session”。我以为我已经正确捕获了我的异常,但没有意识到我的 try/catch 的位置为时已晚! 【参考方案1】:

您可以使用注释来进行更细粒度的事务划分。默认情况下,服务是事务性的,所有公共方法都是事务性的。但是,如果您使用任何 @Transactional 注释,Grails 不会让所有事情都成为事务性的——您拥有完全的控制权。

运行时异常会自动触发回滚,但检查的异常不会。尽管 Groovy 不要求您捕获已检查的异常,但该功能是 Spring 的东西,它不知道 Groovy 异常处理。

事务是通过将服务类实例包装在代理中来实现的。如果一个异常“逃脱”了代理,无论它是否被捕获,回滚都已经发生了。

所以你有几个选择。将updateSomething 注释为@Transactional 但不要注释cleanUpOldFile

import org.springframework.transaction.annotation.Transactional

@Transactional
def updateSomething(domainObj) 
...


def cleanUpOldFile(...) 
   ...

您还可以用一个或多个不应回滚事务的未经检查的异常(或在其他用例中应该回滚的检查异常)来注释 cleanUpOldFile,例如

@Transactional(noRollbackFor=[FooException, BarException])
def cleanUpOldFile(...) 
   ...

【讨论】:

我不完全理解的一件事是,我的 catch 块不应该捕获所有异常,包括运行时和检查的异常吗? Spring 怎么知道我有任何异常? 我认为它注意到服务层之间的异常,在我的情况下,我有一个服务层与另一个服务层通信。这是唯一对我有意义的事情。 如果您所做的只是将@Transactional(noRollbackFor=[FooException, BarException]) 添加到cleanUpOldFile(),那么这对类中的所有其他方法有什么影响?他们是否仍然是事务性的? 如果我指定noRollbackFor=[Exception],这是否仍会针对未捕获的异常回滚? 自 Grails v3.2.0 起,检查异常也会触发回滚。 source【参考方案2】:

除了@Burt Beckwith 的回答之外,如果您有一项服务,您只是不想要交易(在我的情况下我实际上是这样做的),您可以通过添加关闭所有公共方法上的交易

static transactional = false

到服务类。

【讨论】:

是的,这对于不写入数据库的实用程序服务很常见。这是一个很好的性能优化,否则您会为每次调用创建不必要的事务而产生少量成本。

Spring transactions - 新事务中的异常导致父事务中的回滚

】Springtransactions-新事务中的异常导致父事务中的回滚【英文标题】:Springtransactions-Exceptioninnewtransactioncauserollbackinparentone【发布时间】:2020-03-1023:02:04【问题描述】:我正在为使用Propagation.REQUIRES_NEW注释的方法的奇怪行为而苦苦... 查看详情

spring之transactional注解

参考技术A该注解的签名如下:定义零(0)个或多个异常类,这些异常类必须是Throwable的子类,指示哪些异常类型必须导致事务回滚。默认情况下,事务将在RuntimeException和Error上回滚,但不会在检查型异常(业务异常)上回滚。... 查看详情

如何使事务在 Grails 中工作

】如何使事务在Grails中工作【英文标题】:HowToMakeTransactionsWorkInGrails【发布时间】:2010-12-1009:10:16【问题描述】:总结一个父母可以有很多孩子。你如何编写一个服务,如果在添加父级后添加子级时出错,则整个事务会回滚。比... 查看详情

java基础子线程任务发生异常,主线程事务如何回滚?

...个任务,如果执行这个任务过程中发生了异常,如何让主线程捕获到该异常并且进行事务的回滚。二、主线程与子线程先来 查看详情

Grails:未刷新的会话和回滚的事务有啥区别?

】Grails:未刷新的会话和回滚的事务有啥区别?【英文标题】:Grails:Whatisthedifferencebetweenanunflushedsessionandarolledbacktransaction?Grails:未刷新的会话和回滚的事务有什么区别?【发布时间】:2012-03-2111:27:46【问题描述】:我对会话和... 查看详情

spring事务失效的几种场景

1.抛出检查异常导致事务不能正确回滚spring默认只会回滚非检查异常,需要配置rollbackFor属性指定回滚2.业务方法内自己try-cache异常导致事务不能正确回滚事务通知只有捕获到目标抛出的异常,才能进行后续的回滚处理ÿ... 查看详情

spring事务失效的几种场景

1.抛出检查异常导致事务不能正确回滚spring默认只会回滚非检查异常,需要配置rollbackFor属性指定回滚2.业务方法内自己try-cache异常导致事务不能正确回滚事务通知只有捕获到目标抛出的异常,才能进行后续的回滚处理ÿ... 查看详情

spring事务失效的八种场景(代码片段)

文章目录Spring事务失效的八种场景1.抛出检查异常导致事务不能正确回滚2.业务方法内自己try-catch异常导致事务不能正确回滚3.aop切面顺序导致导致事务不能正确回滚4.非public方法导致的事务失效5.父子容器导致的事务失效6.调用本... 查看详情

为什么事务没有回滚!

...--然而,我的事务却没有“回滚”,为此还导致了异常数据的发生,为什么?这是一个发生在我工作中的真实的案例,在用户问我的时候我当时也SB了,在我理解了这背后的原理后,我虽然接受了SQLServer在某些场景下不回滚... 查看详情

事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务

...认情况下,如果被注解的数据库操作方法中发生了unchecked异常,所有的数据库操作将rollback;如果发生的异常是checked异常,默认情况下数据库操作还是会提交的。checked异常:表示无效,不是程序中可以预测的。比如无效的用户... 查看详情

jpa事务中的异常最后不也抛出了,为什么没被catch到而导致回滚?(代码片段)

上周,我们通过这篇文章《为什么catch了异常,但事务还是回滚了?》来解释了,之前test4为什么会回滚的原因。但还是收到了很多没有理解的反馈,主要是根据前文给出的线索去跟踪,是获得到了回滚的... 查看详情

jpa事务中的异常最后不也抛出了,为什么没被catch到而导致回滚?(代码片段)

上周,我们通过这篇文章《为什么catch了异常,但事务还是回滚了?》来解释了,之前test4为什么会回滚的原因。但还是收到了很多没有理解的反馈,主要是根据前文给出的线索去跟踪,是获得到了回滚的... 查看详情

springboot@transactional事务不回滚(代码片段)

一、异常捕获的原因这里Exception异常,他又分为运行时异常RuntimeException和非运行时异常可查的异常(checkedexceptions):Exception下除了RuntimeException外的异常不可查的异常(uncheckedexceptions):RuntimeException及其子类和错误(Error)异常ch... 查看详情

grails:在服务上玩事务(回滚)

howtorollbackdataongrails'service....formyutil-->pleaselookatclassGtestService{ booleantransactional=true deftest()throwsRuntimeException{//testingfortransactionaldefx=newGtest();x.testName="tester";if(!x.save(flush:true)){th... 查看详情

(转)spring异常抛出触发事务回滚策略(代码片段)

背景:在面试时候问到事务方法在调用过程中出现异常,是否会传递的问题,平时接触的比较少,有些懵逼。spring异常抛出触发事务回滚策略Spring、EJB的声明式事务默认情况下都是在抛出uncheckedexception后才会触发事务的回滚 ... 查看详情

spring中@transactional事务回滚(代码片段)

...ing中@Transactional注解,默认情况下只对RuntimeException异常进行事务的回滚。如果事务的方法中抛出unchecked异常(RuntimeException),事务会进行回滚(rollback);如果事务的方法中抛出是checked异常 查看详情

springboot事务管理-事务回滚示例(代码片段)

...。那么,如果发生“检查异常”,我们的交易将如何表现?在发生检查异常的情况下,即使我们使用了事务注释,先前执行的事务也不会自动回滚。我们需要通知应用程序如何在发生检查异常时处理回滚。这... 查看详情

springboot项目中使用@transactional注解不生效导致事务回滚失败问题总结

...是不支持事务的.  3.如果事务回滚失败还要查看出现的异常是checke 查看详情