我们需要能够回滚服务中的复杂事务,而不会向调用者抛出异常.我的理解是,实现这一目标的唯一方法是使用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
}
}
}
Run Code Online (Sandbox Code Playgroud)
以上是有缺陷的 - 我假设"return ob3"不会从方法中返回ob3,因为它在闭包中.不确定如何从闭包内部到外部进行通信.
对于您的主要问题:如果您愿意,可以选择一个随机域对象,它不会造成任何伤害.或者,如果您愿意,您可以找到当前会话并在其上打开一个事务:
grailsApplication.sessionFactory.currentSession.withTransaction { /* Do the things */ }
Run Code Online (Sandbox Code Playgroud)
从文体上来说,我没有偏好.其他人可能.
不确定如何从闭包内部到外部进行通信.
总的来说这可能很难; withTransaction原则上可以返回它想要的任何东西,无论它的闭包参数返回什么.但事实证明,它withTransaction返回其闭包返回的值.在这里,观看:
groovy> println(MyDomainObject.withTransaction { 2 + 2 })
4
Run Code Online (Sandbox Code Playgroud)
按照惯例,所有withFoo采用闭包的方法都应该以这种方式工作,这样才能完成你想要做的事情.