我的 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
您可以使用注释来进行更细粒度的事务划分。默认情况下,服务是事务性的,并且所有公共方法都是事务性的。但如果你使用任何@Transactional
注释,Grails 并不使所有事情都成为事务性的——您拥有完全的控制权。
运行时异常会自动触发回滚,但检查异常则不会。尽管 Groovy 不要求您捕获已检查的异常,但该功能是 Spring 的功能,它不了解 Groovy 异常处理。
事务是通过将服务类实例包装在代理中来实现的。如果异常“逃逸”了代理,无论它是否被捕获,回滚都已经发生。
所以你有几个选择。注释updateSomething
as @Transactional
但不要注释cleanUpOldFile
:
import org.springframework.transaction.annotation.Transactional
@Transactional
def updateSomething(domainObj) {
...
}
def cleanUpOldFile(...) {
...
}
您还可以使用一个或多个不应回滚事务的未经检查的异常(或在其他用例中应回滚的检查异常)来注释 cleanUpOldFile,例如
@Transactional(noRollbackFor=[FooException, BarException])
def cleanUpOldFile(...) {
...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)