我是否需要在 grails 中明确刷新 GORM 保存调用? [英] Do I ever need to explicitly flush GORM save calls in grails?

查看:17
本文介绍了我是否需要在 grails 中明确刷新 GORM 保存调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的情况,似乎表明存在 GORM 缓存问题

I have a strange situation which appears to indicate a GORM cacheing problem

//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   

我不明白为什么最后两个查询会返回不同的结果.

I cannot understand why the last two queries could return different results.

但是,如果我对 book.save(flush:true) 进行以下修改.两个 println 语句都将返回所有书籍.

However if I make the following modification of book.save(flush:true). Both of the println statements will return all books.

我的印象是这在单个应用程序中不是必需的.

I was under the impression that this was not necessary within a single application.

我正在使用的参考

  • 数据库:mysql
  • Groovy:1.7.10
  • Grails:1.3.7

@Hoàng Long

我的问题如下所示,假设 action1/action2 都被多次调用,没有特定的模式

My problem is demonstrated below, suppose action1/action2 are both called many many times, in no particular pattern

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 用于刷新.我的问题是,这是一个过于复杂的解决方案,随着数据库调用复杂性的增加,它无法扩展.

One solution would be to have a flag which is is set by action1 and used by action2 to flush if necessary. My issue is that this is an overly complex solution, which is not scalable as the complexity of DB calls increases.

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
}

推荐答案

在您的情况下,第一条语句返回空列表,因为它从数据库读取数据,但数据尚未存在.

In your case, the first statement return empty list because it reads data from the database, but the data isn't there yet.

Hibernate 的工作原理:当您使用 (flush: true) 调用 save 时,它​​将刷新 Hibernate 会话,将会话中的所有数据立即持久化到数据库中.如果不使用(flush:true),则数据仅记录在Hibernate session 中,并且只有在Hibernate session 刷新时才会持久保存在数据库中.刷新会话的时间由 Hibernate 自动确定以优化性能.

It's how Hibernate works: When you call save with (flush: true), it will flush the Hibernate session, persistent all data in session to database immediately. If not using (flush:true), the data is only recorded in Hibernate session and only get persisted in database when Hibernate session is flushed. The time to flush the session is automatically determined by Hibernate to optimize the performance.

通常,您应该让 Hibernate 为您完成工作(为了优化)——除非您希望数据立即持久化.

Generally, you should let Hibernate do the work for you (for optimization sake) - unless you want the data are persisted right away.

根据彼得·莱德布鲁克的说法:

According to Peter Ledbrook:

让 Hibernate 完成它的工作,并且只有在您需要时才手动刷新会话必须,或至少只有在最后一批更新.你应该只如果你没有看到,真的有用数据库中的数据应该在什么时候那里.我知道这有点一厢情愿,但情况何时需要采取此类行动取决于关于数据库实现和其他因素.

Let Hibernate do it's job and only manually flush the session when you have to, or at least only at the end of a batch of updates. You should only really use if you're not seeing the data in the database when it should be there. I know that's a bit wishy-washy, but the circumstances when such action is necessary depend on the database implementation and other factors.

来自GORM 陷阱 - 第 1 部分

更新:要清楚如何在保存所有对象后一次刷新会话:

UPDATE: to be clear about how to flush the session one time after all the object get saved:

import org.hibernate.*

class SomeController {
  SessionFactory sessionFactory

  def save = {
    assert sessionFactory != null

    // loop and save your books here

    def hibSession = sessionFactory.getCurrentSession()
    assert hibSession != null
    hibSession.flush()
  }
}

这篇关于我是否需要在 grails 中明确刷新 GORM 保存调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆