3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails ActiveRecord Transactionで例外発生時、Rollbackされない問題

Last updated at Posted at 2021-07-05

概要

ActiveRecord Transactionであれば、処理途中で例外が発生した場合は
それまでのinsert、updateをロールバックしてくれると思っていましたが、
書き方によってはロールバックされないことがあるので、
ロールバックされる・されないパターンを整理してみました。

開発環境

  • Ruby 2.6.5
  • Rails 5.2.6

ActiveRecord::Base.transaction

ロールバックされない書き方

  ActiveRecord::Base.transaction do
    user = User.find_by!(name: 'テスト太郎')

        # nameカラムを更新
    user.update!(name: 'テスト太郎更新')

    # Integer型のageカラムにStringを設定
    user.update!(age: 'Invalid Value')
  end
  rescue StandardError => e
    puts '例外エラーが発生しました。'
  end

Integer型のageカラムに 文字列を入れてupdateしたことで例外が発生、
例外エラーが発生しました。 メッセージが出力されるが、
User nameのupdateはロールバックされず、 nameはテスト太郎更新 に更新される。

ロールバックされる書き方

begin
  ActiveRecord::Base.transaction do
    user = User.find_by!(name: 'テスト太郎')

        # nameカラムを更新
    user.update!(name: 'テスト太郎更新')

    # Integer型のageカラムにStringを設定
    user.update!(age: 'Invalid Value')
  end
rescue StandardError => e
  puts '例外エラーが発生しました。'
end

Integer型のageカラムに 文字列を入れてupdateしたことで例外が発生、
例外エラーが発生しました。 メッセージが出力される。
user nameのupdateはロールバックされ、 Userテーブル.nameカラムは更新されず、テスト太郎 のままになる。

感想

Railsを使い始めた頃、これにハマって
ロールバックのテストが通らず、何時間も無駄にしてしまったことがありましたが、
同じチームメンバーがこれにハマっていたのを見て
簡単に書いてみました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?