【问题标题】:Grails 2.5.1 domain.get(id) get cached dataGrails 2.5.1 domain.get(id) 获取缓存数据
【发布时间】:2018-09-06 05:43:04
【问题描述】:

我是 groovy 和 grails 的新手。 Grails 2.5.1 版 Groovy 版本 2.4.5 我的问题是: 我在 customerController 中有一个更新方法。

客户控制器:

def update(){
   def map = [:]
   def customerId = params.id
   def newCustomer = request.JSON
   def customer = customerService.updateCustomer(customerId, newCustomer)

   customer.validate()

   if (customer== null) {
       map['success'] = false
       map['message'] = "Record not found"

       return map
   }

   if (customer.save()) {
       map['success'] = true
       map['data'] = customer
   } else {
       validateErrorService.extractErrors(customer, map)
   }

   return map
}

在更新方法中我调用 customerService.updateCustomer

客户服务:

def updateCustomer(customerId, newCustomer){
    def customer = Customer.get(customerId)

    if (customer == null) {
        return null
    }
    verifyLead(newCustomer.leadId)

    customer.firstName = newCustomer.firstName
    customer.lastName = newCustomer.lastName
    if(!customer.hasErrors())
        customer.save(flush:true)

    return customer
}

然后我调用 verifyLead 方法来更新 Lead 域

def verifyLead(jsonLead, userId){
    Long leadId = jsonLead.id as Long
    Lead lead = Lead.get(leadId)

    lead.status = "Proceed"
    lead.save(flush: true)
}

先导域法 Lead.get(leadId) 返回旧的(缓存的)数据 所以当我保存时: 铅。保存(刷新:真) 它错误hibernate.object.staleException

【问题讨论】:

    标签: grails groovy


    【解决方案1】:

    (我在这里推测,因为我不知道你的设置)

    简短回答: 当域对象(在您的情况下为 Lead)后面的数据库记录在上次从 DB 读取到您的 save() 调用之间更新时,通常会发生 StaleObjectStateException(我想您会得到)。 根据您的设置,它可能是 Grails 应用程序的第二个实例。

    一种可能的解决方案是悲观锁定(请参阅 Grails 文档中的 7.3.5 Pessimistic and Optimistic Locking)。

    更长的答案(如果您已经了解更多技术背景,请原谅): get() 从底层 Hibernate 会话返回一个域对象。此会话不会自动识别数据库中的更改。 因此,如果数据库发生更改,那么您的 Hibernate 会话中的数据可能会变得陈旧。 GORM(Grails 的 DB 层)通常使用乐观锁定(尝试保存并增加 DB 记录的 version 字段的值)。

    如果您的代码尝试保存的域对象的版本低于数据库中对象的版本,那么 GORM/Hibernate 认为抛出异常比更新记录并可能破坏新的更改更好。

    使用悲观锁定,您的代码首先锁定数据库记录或表,然后更新记录,最后释放锁定。

    但要小心:悲观锁定会带来自己的问题。

    【讨论】:

    • 非常感谢您的回复。无论如何,这个问题在 Grails 3.x 中解决了吗?
    • 无论如何,Stefan,无论如何要确保每次我们调用 get() 时 Hibernate 会话都能识别数据库中的更改?
    • @sereyvuth-sok 关于 Grails 3.x:遗憾的是我仍然必须使用 Grails 2.x。关于会话:问题更多在于 DB 记录在 saveing 时是陈旧的,而不是在 getting 从 Hibernate 会话时它是陈旧的。
    猜你喜欢
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 2020-09-17
    • 2021-08-24
    相关资源
    最近更新 更多