Grails 2.5.1 domain.get(id) 获取缓存数据
Grails 2.5.1 domain.get(id) get cached data
我是 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) return 旧(缓存)数据
所以当我保存时:
lead.save(同花顺:真)
它错误 hibernate.object.staleException
(我在这里推测,因为我不知道你的设置)
简答:
当域对象(在您的情况下是 Lead)后面的数据库记录在上次从数据库读取到您的 save()
调用之间更新时,通常会发生 StaleObjectStateException(我想您会得到)。
根据您的设置,它可能是您的 Grails 应用程序的第二个实例。
一种可能的解决方案是悲观锁定(请参阅 Grails 文档中的 7.3.5 Pessimistic and Optimistic Locking)。
更长的答案(如果您已经了解更多技术背景,请原谅):
get()
returns 来自底层 Hibernate 会话的域对象。此会话不会自动识别数据库中的更改。
因此,如果数据库发生变化,那么您的 Hibernate 会话中的数据可能会过时。
GORM(Grails 的 DB 层)通常使用乐观锁定(尝试保存并增加 DB 记录的 version
字段的值)。
如果您的代码尝试保存的域对象的版本低于数据库中对象的版本,那么 GORM/Hibernate 认为抛出异常比更新记录并可能破坏更新的更改更好.
使用悲观锁定,您的代码首先锁定数据库记录或 table,然后更新记录,最后释放锁定。
但要小心:悲观锁定会带来自己的问题。
我是 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) return 旧(缓存)数据 所以当我保存时: lead.save(同花顺:真) 它错误 hibernate.object.staleException
(我在这里推测,因为我不知道你的设置)
简答:
当域对象(在您的情况下是 Lead)后面的数据库记录在上次从数据库读取到您的 save()
调用之间更新时,通常会发生 StaleObjectStateException(我想您会得到)。
根据您的设置,它可能是您的 Grails 应用程序的第二个实例。
一种可能的解决方案是悲观锁定(请参阅 Grails 文档中的 7.3.5 Pessimistic and Optimistic Locking)。
更长的答案(如果您已经了解更多技术背景,请原谅):
get()
returns 来自底层 Hibernate 会话的域对象。此会话不会自动识别数据库中的更改。
因此,如果数据库发生变化,那么您的 Hibernate 会话中的数据可能会过时。
GORM(Grails 的 DB 层)通常使用乐观锁定(尝试保存并增加 DB 记录的 version
字段的值)。
如果您的代码尝试保存的域对象的版本低于数据库中对象的版本,那么 GORM/Hibernate 认为抛出异常比更新记录并可能破坏更新的更改更好.
使用悲观锁定,您的代码首先锁定数据库记录或 table,然后更新记录,最后释放锁定。
但要小心:悲观锁定会带来自己的问题。