Railsのトランザクションとその例外処理


トランザクションとは

一言で表すと、[ここからここまでワンセット]な処理単位のこと。
例えば買い物するときに、

1.代金を払う
2.商品を受け取る

最低限この2つの動作を行うが、仮にこの動作のうち1つだけしかしなかった場合、商品を受け取って代金は払わずにいたとき、それは「買い物」ではなく「物を貰う」行為になる。

2つの動作が合わさって初めて買い物という処理(トランザクション)と言える。

基本構文

ActiveRecord::Base.transaction do
  # 例外が発生するかもしれない処理
end
  # 例外が発生しなかった場合の処理
rescue => e
  # 例外が発生した場合の処理

transactionブロック内で例外が発生した場合、ブロック内で行われたデータベース更新処理が全てロールバックされる。

transactionを機能されるためには例外を発生させる必要がある
つまり save!create!などを使う必要がある

例外処理とは
プログラムがエラーで異常終了するケースでもプログラムを中断させず、別の処理に切り替えるプログラムが例外処理。

rescueは、エラーによって生成された例外オブジェクトを「rescue => e」で受け取り、「e.message」に格納されたエラー内容を表示する。

またrescueにはエラータイプを指定できる。通常のプログラムで発生する可能性の高い例外クラスのStandardErrorが多く適用される。

使い方

こではPayment(入金)PaymentHistory(入金履歴)Modelが存在するとする。入金があると入金履歴も作成する処理を見ていく。

def create
  ActiveRecord::Base.transaction do
    payment = Payment.new(amount: 1000)
    payment.save! # まだコミットされない

    payment_history = PaymentHistory.new(
      amount: 1000,
      payment_day: Time.zone.now.strftime('%Y/%m/%d/%H時%M分%S秒')
    )
    payment_history.save! # まだコミットされない
  end
  true
  # transactionブロックを正常に抜けるとコミットされる
rescue StandardError
  false
end

参考記事

トランザクション
Rubyの例外処理とは?rescueの使い方を中心に徹底解説