我需要批量处理大量记录。每个批次都应该在自己的交易中处理。有没有办法在事务中包装每个批处理并同时批量锁定所有记录?
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
是否在每个批次之后提交事务?
或者我需要在每个批处理中手动放置内部事务块和锁定记录(这意味着还有一个查询)?
我不想放置外部事务块的原因是我想分别提交每个批处理,而不是一次完成。
答案 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