ruby - Rails find_in_batches with locking -
i need process large number of records in batches. , each batch should processed in it's own transaction. there way wrap each batch in transaction , lock records in batch @ same time?
model.scheduled_now.lock.find_in_batches |batch| model_ids = batch.map(&:id) model.update_all({status: 'delivering'}, {"id in (?)" , model_ids}) # creates , updates other db records # , triggers background job perform_delivery_actions(batch) end
does select update
in example commits transaction after each batch? or need put internal transaction block , lock records manually inside each batch (which means 1 more query)?
the reason don't want put outer transaction block want commit each batch separately, not whole thing @ once.
i ended implementing own find_in_batches_with_lock
:
def find_in_batches_with_lock(scope, user, batch_size: 1000) last_processed_id = 0 records = [] begin user.transaction 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