我们需要能够回滚服务中的复杂事务,而不会向调用者抛出异常。我的理解是,实现这一点的唯一方法是使用 withTransaction。
问题是:
下面或多或少是我想要做的。用例用于从帐户中提取并将其存入信用卡。如果转账失败,我们要回滚事务,而不是回滚支付记录日志,必须在单独的事务中提交(使用 RequiresNew)。无论如何,服务方法必须返回一个复杂的对象,而不是一个异常。
someService.groovy
Class SomeService {
@NotTransactional
SomeComplexObject someMethod() {
SomeDomainObject.withTransaction{ status ->
DomainObject ob1 = new DomainObject.save()
LogDomainObject ob2 = insertAndCommitLogInNewTransaction()
SomeComplexObject ob3 = someAction()
if (!ob3.worked) {
status.setRollbackOnly() // only rollback ob1, not ob2!
}
return ob3
}
}
}
以上是有缺陷的 - 我假设“返回 ob3”不会从方法中返回 ob3,因为它在一个闭包中。不确定如何从闭包内部到外部进行通信。
最佳答案
对于您的主要问题:如果您愿意,您可以选择一个随机域对象,它不会造成任何伤害。或者,如果您愿意,您可以找到当前 session 并在其上打开一个事务:
grailsApplication.sessionFactory.currentSession.withTransaction { /* Do the things */ }
从风格上讲,我在这里没有偏好。其他人可能。
Not sure how to communicate from inside a closure to outside it.
一般来说,这可能很难;
withTransaction
原则上可以返回任何它想要的东西,不管它的闭包参数返回什么。但事实证明,withTransaction
返回其闭包返回的值。在这里,观看:groovy> println(MyDomainObject.withTransaction { 2 + 2 })
4
按照惯例,所有
withFoo
采用闭包的方法应该以这种方式工作,正是为了让您可以做您想做的事情。
关于grails withTransaction - 为什么它在域对象上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30033278/