Ruby学習の一環として、週に1度Ruby関連のブログ記事(英語)を翻訳しています。
今回はActiveRecordのtransactionに関する話。
原文:Transactions & Connections in ActiveRecord
↓以下本文↓
ApplicationRecordを継承するクラスは全てデータベースとのやりとりができるということは、おそらくご存知だと思います。それってどういうことなんでしょう?モデルはみな均等(equivalent)なのでしょうか?
以下の2つの違いは何でしょうか?
ApplicationRecord.transaction do
user.save!
post.save!
end
---
User.transaction do
Post.transaction do
user.save!
post.save!
end
end
答えは……まあもちろん、場合によりけりですよね。
正確にはデータベースとのコネクションによります。それぞれのモデルが各々データベースとのコネクションを持つ場合があります。User.connection
,やPost.connection
で簡単に確認できます。
シンプルに、一つのモデルに対して一つのデータベースしかない場合は、モデルはみな均等(equivalent)ということになります。
しかし例えばapartment
などのgemを使って複数のデータベースにまたがっていたりexcluded_model
を持っている場合は、話は全然違います。特にexcluded_models
は他のモデルたちとは異なるコネクションをもつことになります。その結果…
- それぞれのコネクションの中で処理がなされるので、上記のコードの1つ目は機能しない
- トランザクションは複数コネクションにまたがることができないため、2つ目の処理をしなければなくなる
要するに、モデルとデータベースが1対1で対応しているケースであれば、ApplicationRecord.transaction
は問題なく使える、ということです。
↑本文ここまで↑
自分用メモ:
# 確かApplicationRecordクラスにあった説明文…
# -----------------------------------------------------
# So basically you should use transaction blocks whenever you
# have a number of statements that must be executed together or not at all.
# 複数の処理を1つのトランザクション内に納めたい場合、transactionメソッドを使う
#
# For example:
#
# ActiveRecord::Base.transaction do
# david.withdrawal(100)
# mary.deposit(100)
# end
transactionメソッドはクラス : テーブルが1:1であることを前提にしている。