Rails find_in_batches带锁定

时间:2016-06-01 19:25:16

标签: ruby-on-rails ruby ruby-on-rails-3

我需要批量处理大量记录。每个批次都应该在自己的交易中处理。有没有办法在事务中包装每个批处理并同时批量锁定所有记录?

Model.scheduled_now.lock.find_in_batches do |batch|
  model_ids = batch.map(&:id)
  Model.update_all({status: 'delivering'}, {"id IN (?)" , model_ids})

  # creates and updates other DB records
  # and triggers background job
  perform_delivery_actions(batch)
end

此示例中的SELECT FOR UPDATE是否在每个批次之后提交事务? 或者我需要在每个批处理中手动放置内部事务块和锁定记录(这意味着还有一个查询)?

我不想放置外部事务块的原因是我想分别提交每个批处理,而不是一次完成。

1 个答案:

答案 0 :(得分:1)

我最终实现了自己的find_in_batches_with_lock

def find_in_batches_with_lock(scope, user, batch_size: 1000)
  last_processed_id = 0
  records = []
  begin
    user.transaction do
      records = scope.where("id > ?", last_processed_id)
                     .order(:id).limit(batch_size).lock.all
      next if records.empty?
      yield records
      last_processed_id = records.last.id
    end
  end while !records.empty?
end