ruby
1class User < ApplicationRecord 2 after_save { raise ActiveRecord::Rollback } 3end 4 5class Article < ApplicationRecord 6end
上記を前提として以下をrails consoleで実行していきます。
まず外側のtransactionに、joinable: false
オプションを追加して、
内側のtransaction( update!が自前で作るtransaction )が外側のtransactionにjoinしないようにします。
rails consoleで以下を実行した場合、Userはafter_save
コールバックがあるのでROLLBACKして、nameの更新がおこなれません。
しかし、Articleは普通に保存されます。
ruby
1# rails consoleで以下実行 2ActiveRecord::Base.transaction(joinable: false) do 3 User.first.update!(name: "new_name") 4 Article.first.update!(title: "new_title") 5end
結果としては、Userは更新されて、Articleは更新されないという状態になります、
これって、内側のtransaction2つの原子性は保たれてるけど、外側のtransactionの原子性は保たれていないような気がします。
Userのほうは失敗してるんだから、外側のtransactionもROLLBACKするような作りになっていないのがすごく違和感あります。
これは仕方ないのでしょうか、みなさんはどのように思いますか?
補足
実際に試してみた所、
after_save { raise ActiveRecord::Rollback }
じゃなくて
after_save { raise ActiveRecord::RecordInvalid}
after_save { raise }
のように、ActiveRecord::Rollback
以外をraiseすればちゃんと外側のtransactionもROLLBACKするみたいですね
なので、ActiveRecord::Rollback
だけ例外って理解しておけばいいのかな

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。