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

标签 grails transactions grails-orm

我的 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

最佳答案

您可以使用注释来进行更细粒度的事务划分。默认情况下,服务是事务性的,所有公共(public)方法都是事务性的。但是如果你使用任何 @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(...) {
   ...
}

关于grails - Grails下如何防止异常导致事务回滚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15823677/

相关文章:

grails - 如何在Spock集成测试中为每个测试类设置transactionnal选项?

grails - 如何在 Intellij 中停止执行 grails?

grails - 调用grails run-script时发生异常:创建名称为 'grailsApplication'的bean时出错

database-design - 如何移动排序列表中的元素并保持 CouchDb 写入 "atomic"

performance - Grails hibernate session 批量

mysql - Grails 子查询

java - 您可以将 Controller 列表参数与 Hibernate 标准结合起来吗?

grails - 如何在Grails中使用Hibernate HQL检索列值

grails - Grails 中的 Controller 默认是事务性的吗?

java - Spring事务边界和DB连接保持