我需要的:
确保原子更新(无记录可以处理2次)
>所有1000行的批量删除
@queue = Queue.where("col = 1").limit(1000) ids = [] @queue.each do |row| Queue.do_something(row) ids << row.id end Queue.delete_all("id in (#{ids.join(',')}) ")
是相同的
Queue.transaction do @queue.each do |row| Queue.do_something(row) Queue.delete(row.id) end end
解决方法
对于插入:
使用事务时,ActiveRecord不会执行批量插入.但是,由于使用单个事务来执行所有INSERT语句,而是使用每个INSERT语句,而是使用一个事务,因此它会加快速度.
所以:
Queue.transaction do @queue.each do |row| # an INSERT is done here end end
将要快于:
@queue.each do |row| # an INSERT is done here end
有关如何真正做批量插入的更多信息,请查看这个article.
对于删除:
ActiveRecord delete_all调用是一个单独的sql DELETE语句,所以我猜你可以将其视为批量删除(不需要使用这里的事务,因为它已被ActiveRecord封装在一个事务中).在每个记录上调用delete时不是这种情况,这将导致多个sql DELETE语句,从而启动和提交多个事务并且整体性能较差.