Grails中的update
操作首先检查要更新的对象的版本,然后对其进行更新。
在检查版本和更新对象期间,Grails的哪一部分确保对象不会被另一个请求更新?
更新
是的,hibernate会在savin对象时检查版本并抛出异常,乐观锁定失败。我想hibernate会确保check + update是原子的,但是......
如果你看看grails生成的更新方法,你会发现grails首先进行双重检查,然后(从我的角度来看)不准备处理异常。在更新方法已经检查了正确版本之后,hibernate将抛出异常的可能性很小,但对我来说似乎是可能的。
那么尝试保存并捕获异常(如果有的话)是不够的?
答案 0 :(得分:4)
它由Hibernate层管理。它被称为'乐观锁定',基本上它只更新具有已知版本的对象。喜欢:
UPDATE SET
%... fields ...%,
version = version + 1 --update version to a new value
WHERE
id = %obj id% --current object
AND version = %previous obj version%` --last known version
当它无法更新时抛出异常(顺便说一句,此时很难从这个错误中恢复,在大多数情况下你只是丢失了更新)。
如果您想确保保存数据,请尝试强制保存数据(并检查保存/验证错误):
try {
if (!obj.save(flush: true)) {
// validation error
}
} catch (OptimisticLockingFailureException e) {
// not saved
}
甚至在更新前锁定数据。仅当您有大量并发更新时才有用。
MyDomain obj = MyDomain.lock(params.id) //now it's locked for update
// update fields
obj.save()
查看有关GORM锁定的更多详细信息