我遇到了一个奇怪的情况,似乎表明存在 GORM 缓存问题
//begin with all book.status's as UNREAD
Book.list().each { book.status = Status.READ ; book.save() }
println (Book.findAllByStatus (Status.READ)) //will print an empty list
println (Book.list().findAll (it.status == Status.READ)) // will print all books
我无法理解为什么最后两个查询会返回不同的结果。
但是,如果我对 book.save(flush:true) 进行以下修改。两个 println 语句都将返回所有书籍。
我的印象是在单个应用程序中没有必要这样做。
仅供引用,我正在使用
- 数据库:mysql
- Groovy:1.7.10
- Grails:1.3.7
@Hoàng Long
我的问题如下所示,假设 action1/action2 都被调用了很多次,没有特定的模式
def action1 = {
Foo foo = Foo.get(params.id)
//... modify foo
foo.save() //if I flush here, it will be inefficient if action1 is called in sequence
}
def action2 = {
//if I flush here, it will be inefficient if action2 is called in sequence
List<Foo> foos = Foo.findAllByBar (params.bar)
//... do something with foos
}
一种解决方案是使用一个标志,该标志由 action1 设置并由 action2 在必要时用于刷新。我的问题是,这是一个过于复杂的解决方案,随着数据库调用复杂性的增加,它无法扩展。
boolean isFlushed = true
def action1 = {
Foo foo = Foo.get(params.id)
//... modify foo
foo.save()
isFlushed = false
}
def action2 = {
if (!isFlushed) {
//flush hibernate session here
}
List<Foo> foos = Foo.findAllByBar (params.bar)
//... do something with foos
}
最佳答案
Do I ever need to explicitly flush GORM save calls in grails?
简而言之是!,如果您想像在代码中那样立即使用该对象。
我遇到了同样的问题,所以这是我阅读一些引用资料后得到的图片。
这是休眠 session 问题。
Hibernate session 在调用 Controller 操作时创建,并在操作返回时结束(或因错误而提前终止)。如果代码没有调用任何事务代码,Hibernate 的数据库交互可以如下描述:
假设条目操作名称为 actionName 并且对该操作的调用完成且没有任何错误。
注意:中间的栏(二级缓存已禁用),因为没有任何事务代码。
如果上述相同代码有错误:
但是,如果您的操作正在调用事务方法或正在使用 withTransaction 创建内联事务(并假设对操作的调用已完成且没有任何错误)。
如果上面的代码有错误:
我希望它有所帮助,但如果我犯了任何错误或错过了要点,请评论我,我会更新我的照片。
关于grails - 我是否需要在 grails 中显式刷新 GORM 保存调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6288991/