読者です 読者をやめる 読者になる 読者になる

[rails] transaction中、一定間隔でcommit

============== 6/15 追記(start) ====================
ARを使用しての更新系バッチ処理の選択肢としては、

  • 毎回commitされてしまう(default)
  • 最後に一回commit(transactionメソッドを使用)

が一般的なようで、複数件毎にcommitする方法が見当たらない…
ARのソースを追っていけば何かわかると思い、

grep COMMIT *

からスタート…
============== 6/15 追記(end) ====================


成功したのでとりあえず張り付け

require 'csv'

class Price < ActiveRecord::Base
  class << self
    def import(filepath, commit_interval = 100)
      Price.transaction do
        transaction_cnt = 0
        CSV.foreach(filepath) do |row|
          rec_year, rec_month, rec_day = row[0].split('/')
          rec_time  = row[1]
          rec_start = row[2]
          rec_high  = row[3]
          rec_low   = row[4]
          rec_end   = row[5]
          updated = Price.find(:first,
                               :conditions=>["year = ? and month = ? and day = ? and time = ?",
                                             rec_year, rec_month, rec_day, rec_time])
          if updated
            updated.update_attributes(:start=>rec_start,
                                      :high =>rec_high,
                                      :low  =>rec_low,
                                      :end  =>rec_end)
          else
            Price.create(:year=>rec_year,
                         :month=>rec_month,
                         :day=>rec_day,
                         :time=>rec_time,
                         :start=>rec_start,
                         :high=>rec_high,
                         :low=>rec_low,
                         :end=>rec_end)
          end
          transaction_cnt += 1
          if (transaction_cnt % commit_interval) == 0
            Price.connection.commit_db_transaction
          end
        end
      end
    end
  end
end


============== 6/15 追記(start) ====================
ARがconnectionを公開してくれていて助かった。肝は以下のメソッド。

Price.connection.commit_db_transaction

途中、includeとかextendを試したけどうまくいかなかった…
クラスに対する操作かインスタンスに対する操作か途中から混乱してくる…
あと、はまった点は、カウンタをインクリメントする際、++が利かなかったこと。

transaction_cnt++     ←NG

============== 6/15 追記(end) ====================