Rails tips: ActiveRecordのトランザクションの概要(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Rails tips: ActiveRecordのトランザクションの概要(翻訳)

トランザクションとは、データベースレコードの作成といった細かな操作の集合であり、多くの場合、外部API呼び出しと組み合わせられます。たとえばゲストブックアプリを作成していて、ゲストの何人かがレコード作成に失敗することがあったとしても大したことはありませんが、オンラインストアでユーザーに課金するときにどこかでうまくいかなかった場合のことを考えてみましょう。

連続した操作のどこかで何かが失敗したら、そこまでの変更を取り消して、再度ユーザーに情報の入力と操作の再開を促したくなるでしょう。失敗した処理中に作成されたレコードはすべて削除しなければなりません。こうした処理はRailsのトランザクションでも行えます。

Railsのトランザクション作成

モデルのクラスやモデルのインスタンス(より一般的にはActiveRecord::Base)で.transactionを呼び出さなければなりません。用途に応じて最適な方法を選びます。1つのトランザクションは、そのモデルのインスタンスではなく、1つのデータベース接続に紐付けられます。

Order.transaction do
  @order.charge_credit_card!
  @user.order_histories.create!(@order)
end
@order.transaction do
  @order.charge_credit_card!
  @user.order_histories.create!(@order)
end
ActiveRecord::Base.transaction do
  @order.charge_credit_card!
  @user.order_histories.create!(@order)
end

トランザクションが失敗したとき

ぜひとも覚えておいていただきたい重要事項は、トランザクションのロールバックはエラーがraiseされたときしか行われないことです。トランザクションのブロック内でfind_byメソッドを使うなら、find_by!を使ってアプリで何らかの問題が生じたときにエラーがスローされるようにすべきです。トランザクションがロールバックした後でエラーがトランザクションブロックの外でraiseされ、エラーがキャッチできるようになります。

トランザクションを静かにロールバックさせたいのであれば、単にトランザクションブロック内でActiveRecord::Rollbackをraiseします。

トランザクションの詳細について

本記事はRailsトランザクションの概要をご紹介いたしました。ネストしたトランザクションやコールバックについても言及する値打ちがありますので、今後の記事にご期待ください。

Railsでお困りの方にお知らせ

知りたいことがありましたら、twitter または連絡用フォームにてお気軽にお問い合わせください。

RSpec & TDDの電子書籍を無料でダウンロード

もっと稼ぎたい方や会社をさらに発展させたい方へ: テスティングのスキルの重要性にお気づきでしょうか?テストを正しく書き始めることが、唯一のファーストステップです。無料でダウンロードいただける私の書籍『RSpec & Test Driven Developmentの無料ebook』をどうぞお役立てください。

関連記事

アトミックなトランザクションで冪等APIを強化する(翻訳)

Railsのトランザクションと原子性のバグ(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ