with_lock 是否锁定块内的所有内容?

vin*_*nce 5 postgresql activerecord locking ruby-on-rails pessimistic-locking

锁定块中的所有模型还是with_lock仅锁定模型本身?例如下面是item里面的所有模型都with_lock被锁定还是只是entry模型被锁定?

class Entry < ApplicationRecord
  enum state: [:pending, :posted]
    
  has_many :items, dependent: :destroy
 
  def post!
    with_lock do
      return unless pending?
      items.each { |i| i.post! }
      self.posted!
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

rml*_*erd 9

with_lock获取单个实例上的行级悲观锁。with_lock只是将锁和事务语句合二为一,因此等价于:

Entity.transaction do
  entity_instance.lock!
end
Run Code Online (Sandbox Code Playgroud)

您正在with_lock模型内部调用,因此您实际上正在执行self.with_lock. 也就是说,您正在获取 的当前实例的锁Entity。除非您也明确锁定单个Item记录,否则它们不会被锁定。不过,对它们的更改确实包含在同一父事务中。