我们遇到了一个奇怪的问题,即第一个请求中创建了对象,但是第二个请求中没有返回它们。 假设我们有两个域类:
Class A {
static hasMany = [bs: B]
def afterUpdate() {
this.addToBs(new B(a: this))
this.save()
}
}
Class B {
static belongsTo = [a: A]
}
当通过PUT /as/<id>
在A的实例上发送了广告时,update()
会在RestfulController
注释@Transactional
。
我们可以观察到,在返回第一个请求的响应之后,API消费者每隔一段时间发送一个后续请求,GET /bs
不会返回B的新实例。已在第一个请求中创建,并在进一步请求时返回。
我预计一旦提交了事务,grails只会将响应发送给API使用者,这意味着下一个请求应该看到该事务的所有更改,不应该吗?
这种行为可能是什么原因?在grails应用程序已将响应发送给API使用者之后,事务是否已提交?如果是这样,@Transactional
围绕update()
默认启用的原因是什么?
我知道在这个示例中,afterUpdate
中的代码也可能被放入beforeUpdate
,但我只是尽力简化示例。
答案 0 :(得分:0)
根据我的经验,afterUpdate()
中的代码等不包含在交易中。您必须明确创建一个事务(也可能是一个会话)。见http://docs.grails.org/latest/ref/Domain%20Classes/withTransaction.html
我建议afterUpdate()
和朋友中的GORM更新,因为它会导致这样的奇怪问题,并且难以对域模型进行单元测试。如果您将保存委托给事务服务,不仅可以正常工作,还可以通过集成测试进行确认。
在我的Grails应用程序中,我保持控制器非常愚蠢:
我将所有业务逻辑保留在服务中,因为控制器很难测试。这是一个例子:
@grails.transaction.Transactional
class SomeService {
def saveA(A a) {
// This method will run in a transaction.
a.addToBs(new B(a: this))
a.save()
}
}
在控制器......
class SomeController {
def update() {
...
someService.save(a)
}
}