跳至内容 跳至搜索

什么是乐观锁

Optimistic 锁允许多个用户访问同一个记录进行编辑,并假设数据冲突最少。 它通过检查自打开记录以来是否有其他进程对其进行了更改来实现这一点,如果发生了这种情况,将抛出一个 ActiveRecord::StaleObjectError 异常,并且更新将被忽略。

查看 ActiveRecord::Locking::Pessimistic 以了解替代方案。

用法

如果存在 lock_version 字段,Active Record 支持乐观锁。 对记录的每次更新都会增加整型列 lock_version,并且锁定机制确保两次实例化的记录将允许最后保存的记录引发 StaleObjectError,如果第一个记录也被更新。 示例

p1 = Person.find(1)
p2 = Person.find(1)

p1.first_name = "Michael"
p1.save

p2.first_name = "should fail"
p2.save # Raises an ActiveRecord::StaleObjectError

Optimistic 锁将在对象被销毁时也会检查数据是否陈旧。 示例

p1 = Person.find(1)
p2 = Person.find(1)

p1.first_name = "Michael"
p1.save

p2.destroy # Raises an ActiveRecord::StaleObjectError

然后您负责处理冲突,方法是捕获异常,并回滚、合并或以其他方式应用解决冲突所需的业务逻辑。

这种锁定机制将在单个 Ruby 进程中起作用。 要使其在所有 Web 请求中起作用,建议的方法是将 lock_version 添加为一个隐藏字段到您的表单中。

可以通过设置 ActiveRecord::Base.lock_optimistically = false 来关闭此行为。 要覆盖 lock_version 列的名称,请设置 locking_column 类属性

class Person < ActiveRecord::Base
  self.locking_column = :lock_person
end
命名空间