什么是乐观锁定¶ ↑
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
命名空间