Open3
トランザクション内で例外キャッチするとロールバックされない
class Klass
ActiveRecord::Base.transaction do
# ① 例外が発生し得る処理
rescue StandardError => e
# ② 例外処理
end
end
このコードではトランザクション中に例外が発生した場合に、ロールバックされない。
例外発生直後に rescue されてしまうため。
class Klass
begin
ActiveRecord::Base.transaction do
# ① 例外が発生し得る処理
end
rescue StandardError => e
# ② 例外処理
end
end
このように transaction ブロックの外側でキャッチさせるとロールバックしてくれる。
①で例外が発生 → transaction メソッドがロールバックを行い、直前で発生した例外を返す → begin 式内で例外がキャッチされ、②の例外処理を実行する
参考記事
- https://qiita.com/ytnk531/items/a0db31ee4311425a3933
-
https://www.youtube.com/watch?v=hfXOC314lJc (
transaction
,within_new_transaction
深堀り) - https://qiita.com/jnchito/items/3ef95ea144ed15df3637 (そもそも例外処理を実装する必要性)
もう少し掘る
begin
commit_transaction
rescue ActiveRecord::ConnectionFailed
transaction.invalidate! unless transaction.state.completed?
raise
rescue Exception
# ロールバックし、元の例外を返す
rollback_transaction(transaction) unless transaction.state.completed?
raise
end
- transaction ブロック内で例外を検知
- ロールバックして、直前の例外を返す(
within_new_transaction
メソッド) - begin ブロックで返された例外を検知して rescue される