跳至内容 跳至搜索

什么是乐观锁定

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
命名空间