.png)
【Ruby on Rails】中級者なら押さえておきたいTransactionについて
「Ruby on Railsで仕事を得るために実務に使える知識が欲しい」
「Progateで学んだ知識からさらにもう一歩ステップアップしたい」
本記事では中級者になるために必ず押さえておきたい「Transaction (トランザクション)」について解説します。
Transactionとは
Transactionとは「ある範囲を1セットの処理とし, どこかで処理が失敗したら全ての処理を巻き戻す」機能です。
具体的な書き方を見てみましょう。
ActiveRecord::Base.transaction do
# 処理の内容
end
ActiveRecord::Base.transaction do
とend
の間に1セットにしたい処理を書いていきます。
これだけだと「どういう場面でつかうの...?」という疑問が出てきますね。
次から詳しく解説していきます。
具体的な使い道
Transaction処理を書いていない場合の失敗例
ではいつ「全ての処理を巻き戻さなくてはならない」シーンが出てくるのでしょうか?
今回は、銀行のシステムを例に考えていきます。
[前提]
(1) 口座のモデル名はAccount,預金額
のカラム名はdeposit
ここで「Aさんの口座からBさんの口座に送金する」例を考えてみましょう。
まずは2人の預金額をみてみます。
account_a = Account.find_by(user_id: 'id_a')
account_b = Account.find_by(user_id: 'id_b')
account_a_deposit = account_a.depsit # Aさんの元々の預金額
account_b_deposit = account_b.depsit # Bさんの元々の預金額
p "Aさんの預金額は#{account_a_deposit}円, Bさんの預金額は#{account_b_deposit}円 です"
[実行結果]
Aさんの預金額は40000円, Bさんの預金額は40000円 です
2人とも預金額は40,000円のようです。
ではここから送金の処理を書いていきます。今回は20000円を送金してみましょう。
remittance = 20000 # 送金額
account_a.update!(deposit: account_a_deposit - remittance )
account_b.update!(deposit: account_a_deposit + remittance )
[実行結果]
ActiveRecord::RecordInvalid: Validation failed: 預金額は50000円までです
実行した結果、処理が失敗してしまいました。この銀行では預金額は50000円以上にはできないようです。 (変な銀行ですね)
ここで、再度Aさんの口座とBさんの口座の預金額を見てみましょう。
[実行結果]
Aさんの預金額は20000円, Bさんの預金額は40000円 です
なんと、Aさんの口座からお金が減っています!! これは送金失敗にもかかわらず、Aさんの預金口座の減額処理が巻き戻っていないからですね。
Transaction処理を使った例
ではこのコードを正しく書き直してみましょう。
「Aさんの口座からの減額処理」と「Bさんの口座からの減額処理」は1セットにならないといけないので、これをTransactionで囲います。
ActiveRecord::Base.transaction do
remittance = 20000 # 送金額
# 以下の処理は1まとめ
account_a.update!(deposit: account_a_deposit - remittance )
account_b.update!(deposit: account_a_deposit + remittance )
end
[実行結果]
ActiveRecord::RecordInvalid: Validation failed: 預金額は50000円までです
実行すると同じように処理が失敗します。(預金額の上限は変えていないため)
さて、Aさんの口座とBさんの口座の預金額を見てみましょう。
[実行結果]
Aさんの預金額は40000円, Bさんの預金額は40000円 です
2人ともお金が減っていないことが確認できました 🎉
まとめ
本記事では中級者以上なら必ず押さえておきたいTransactionについて解説しました!
安全なシステムを作るために、必ず押さえておきましょう。