Grails2.5.1 domain.get(id)获取缓存数据

Grails2.5.1 domain.get(id)获取缓存数据,grails,groovy,Grails,Groovy,我是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, new

我是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.getleadId返回旧缓存数据 因此,当我保存时: lead.saveflush:正确
这是一个错误hibernate.object.staleException

我在这里猜测,因为我不知道您的设置

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

一种可能的解决方案是悲观锁定,请参见Grails文档

如果你已经知道更多的技术背景,请原谅我回答: get从底层Hibernate会话返回域对象。此会话不会自动识别数据库中的更改。 因此,如果数据库发生变化,那么Hibernate会话中的数据可能会过时。 Grails的GORM DB层通常使用乐观锁尝试保存并增加DB记录的version字段的值

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

使用悲观锁定,代码首先锁定DB记录或表,然后更新记录,最后释放锁


但要小心:悲观锁定也会带来问题。

非常感谢您的回复。这个问题在Grails 3.x中解决了吗?Stefan,ho,确保Hibernate会话在每次调用get时都能识别数据库中的更改?@sereyvuth sok关于Grails 3.x:遗憾的是,我仍然必须使用Grails 2.x。关于会话:问题更多的是DB记录在保存时过时,而不是从Hibernate会话获取时过时。