アプリケーション内で、削除と新規作成など複数のデータベース操作を連続して行うケースがある。
この場合、途中でエラーが発生すると、データの不整合が生じるリスクがある。
対応策
関連する複数のデータベース操作をトランザクションでまとめて実行する。
トランザクションを使うことで、すべての操作が正常に完了した場合のみコミットし、どれか一つでも失敗した場合は全てロールバックされ、データの整合性を確保できる。
トランザクション対応が必要な主な場面
- 複数テーブルにまたがるデータ更新
- 例:親レコードと子レコードを同時に作成・削除・更新する場合
- 一連の業務処理で複数のDB操作がある場合
- 例:ユーザー登録時に、ユーザー情報と初期設定情報を同時に登録する場合
- 既存データの削除と新規データの作成を組み合わせる場合
- 例:プラン変更時に古いデータを削除し、新しいプランを登録する場合
- 複数の更新系APIやバッチ処理などで失敗時にロールバックしたい場合
- 例:注文処理で在庫数の更新と注文履歴の作成を同時に行う場合
- 業務上、一貫性・整合性が非常に重要な処理
- 例:会計処理や在庫管理など、データのずれがビジネス上致命的になる操作
コード例(Ruby on Railsの場合)
ActiveRecord::Base.transaction do
# 例)既存データの削除
model_instance.destroy!
# 例)新規データの作成
AnotherModel.create!(attributes)
end
このようにトランザクションを利用することで、複数のデータベース操作を安全に実行することが可能。
!(バン)付きメソッドを使うべき理由
ActiveRecordのdestroy!やsave!など、末尾に「!」が付いたメソッドは、処理に失敗した際に例外(エラー)を発生させる。
この例外が発生することで、トランザクションブロック内でエラーが検知され、すべての処理がロールバックされるため、不完全なデータ更新を防ぐ。
一方、「!」がないメソッドは失敗してもfalseを返すだけで、トランザクションがロールバックされず、意図しない不整合が生じることがある。