複数のテーブルが関係するトランザクションで、Rails と MySQL データベースがテーブル/行のロックをどのように処理するかについて興味があります。
一度に多くのレコードを更新する必要がある状況がありますが、関連する複数のレコードも更新する必要があります。すべてのレコードがすべて更新されていることを確認する必要があり、更新に失敗した場合は変更がロールバックされます。
これには ActiveRecord::Base.transaction ブロックを検討しましたが、同僚が関係するモデルのテーブル ロックについて尋ねました。
これが私のコードの非常に簡素化された例です:
Change.transaction do
Change.all.each do |change|
new_item = Item.new
new_trait = Trait.new
new_trait_value = TraitValue.new
new_trait.options << new_trait_value
new_item.traits << new_trait
new_trait.save
end
end
ノート:
- 15,000 以上の変更レコードが存在する可能性があります
- 現在、約24,000件のアイテムレコードがあります
- 現在、約 38,000 の特性レコードがあります。
- 現在、約 380,000 の TraitValue レコードがあります
- 最初のテストでは、これが非常に長時間実行されるタスクであることが示されています - 数秒ではなく数分で測定されます。
このシナリオでは、4 つのテーブルすべてがロックされていますか? それとも変更テーブルだけがロックされていますか?
4 つのテーブルすべてがロックされていて、プロセスが完了するまでに数分かかる場合、他のユーザーが Item レコードを追加/更新するのを妨げたくないので、トランザクションの使用は私の状況には適していない可能性があります。