1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】transaction 入門

Last updated at Posted at 2020-05-04

Rails における transaction とは?

ざっくり言うと、ActiveRecordの処理(DBのSQL操作であるcreate, update, deleteなど)を保護するもの

よくわからないかもしれないので、次のような入力されたパラメーターの商品を登録する際に、送料を商品の価格に応じて割引くような一連の処理があったとします。

ActiveRecord::Base.transaction do
  product = Product.create!(product_params) # product_params 内のデータをもとに product インスタンスを作成する
  shipping_fee = product.price / DISCOUNT_RATE # 価格を DISCOUNT_RATE で割ったものを送料 shipping_fee とする
  product.update!(shipping_fee: shipping_fee) # 商品インスタンスの送料を登録(更新)する
  end
end

ここでのActiveRecordの処理は2つ、

product = Product.create!(product_params)
product.update!(shipping_fee: shipping_fee)

ですね。

これらが、

ActiveRecord::Base.transaction do

end

で囲まれることで、この範囲内のActiverecordの処理は一連の処理として保護されます。

どういうことか?というと、例えば1つ目のActiveRecord処理であるproductインスタンスの作成(create!)は成功したとして、次の送料計算でもしDISCOUNT_RATE0だった場合、0除算でZeroDivisionErrorが発生します。

shipping_fee = product.price / DISCOUNT_RATE # DISCOUNT_RATE = 0 なので 0除算が発生する

ZeroDivisionError: divided by 0

このようにエラーが発生すると、直ちにロールバック処理が行れ、transactionで囲まれた範囲内のActiveRecordの処理は全てもとの状態に戻ります(処理前のcreateされていない状況)。
また、その次のupdate!の処理でエラーが発生した場合も同様で、その以前のActiveRecord処理であるcreate!はもとの状態に戻ります。

この全てもとに戻ってくれるということが非常に大事、つまりtransactionを使う意義があるのです!

例えばお金のやり取りに関わる一連の支払処理があったとすると、全ての処理が完璧でないと一連の処理としてOKではなく、どこか1つでも処理に誤りがあればその一連の処理はすべてダメという処理が必要な場合が多々あります。
そうでないと、例えばお金を渡す人、お金を受け取る人のどちらかが得する、損することなどになりかねず、サービスとしては致命的な設計となります。

では、なぜ?何を?トリガー(引き金)にロールバックが起こるのでしょうか?
察しが良い方は気づかれていると思いますが、エラー(例外)が発生したからです。
つまりこの例外が発生することがtransactionでのロールバックが起こるトリガーになるのです!←ここ、とても重要ですよ。

以上を踏まえると、transaction内で例外が発生する実装でなければなりません。
次のセクションでは、例外を起こすために気をつける実装例を紹介いたしますので参考にしていただければと思います。

例外を発生させる実装

左側での記述では例外が発生しない(失敗してもfalsenilを返すだけ)ので、右側の記述へ変更して下さい。

save => save!
create => create!
update => update!
destroy => destroy!
find_by => find_by!

それ以外に覚えておくものも書いておきます。

find # findはそのままエラーをはきます
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?