バッチ処理はtransactionsを使用する

Overview

transactionを利用することで、データの不整合を防ぐことができるようになる。

Motivation/Context

ループの中でsaveメソッドを使う時なんかにtransactionがないと途中までデータが登録されて二度目の実行で重複したりと、不都合が発生する。

transactionを使用することで、「全件成功で一括登録」みたいなことができるようになる。

Get Started!!

transactionを利用しない場合

def self.create_users_from_csv!(csv_path)
  CSV.foreach('users.csv') do |row|
    user = User.new
    user.name = row['name']
    user.email = row['email']
    user.save! # ここで毎回トランザクションが開始&コミットされる
  end
end

transactionを使用する場合

def self.create_users_from_csv!(csv_path)
  # トランザクション開始
  self.transaction do
    CSV.foreach('users.csv') do |row|
      user = User.new
      user.name = row['name']
      user.email = row['email']
      user.save! # ここではまだコミットされない
    end
  end
  # transactionブロックを正常に抜けるとコミットされる
end