トランザクションを張る範囲として妥当なのはどれですか。
複数テーブルを更新して、片方だけ成功すると不整合になる箇所に張ります。範囲は必要最小限にし、外部APIの呼び出しのような外部通信は中に入れません。ロックを長く持つためです。
面接官が見ているのは「なんとなく囲む」ではなく境界を意識しているか。
よくある答えと、面談でどう見られるか
- 複数テーブルを更新し、片方だけ成功すると不整合になる範囲だけを最小限に囲む
その通りです。DB::transaction() のクロージャ形式なら例外時に自動でロールバックされます。 - コントローラのアクション全体を囲む
安全に見えますが範囲が広すぎます。中に外部API呼び出しが入ると、応答待ちの間ロックを握り続けます。 - 読み取り処理も含めて、DB に触る箇所はすべて囲む
読み取りだけなら通常は不要です。無駄にロックと負荷が増えます。 - 外部API呼び出しも含めて囲み、失敗したら全部戻す
外部APIはロールバックできませんし、応答待ちの間ずっとロックが残ります。最も避けるべき構成です。
面接官は何を見ているか
- 複数テーブルを更新する処理に張る、という基準を言えた
- DB::transaction() のクロージャ形式に触れた
- 範囲を広げすぎない意識があった
模範解答
複数のテーブルを更新して、片方だけ成功すると不整合になる箇所に張ります。注文の作成と在庫の減算、のような組み合わせが典型です。DB::transaction() のクロージャ形式を使えば、例外時に自動でロールバックされます。範囲は必要最小限にします。中に外部API呼び出しを入れると、応答待ちの間ロックを握り続けることになるので避けます。
ここからどう深掘りされるか
この問いに答えられた場合、面談は次の質問に進みます。
観点をすべて押さえられた場合
デッドロックが起きたらどうなりますか。一部しか触れられなかった場合
トランザクションを張らずに複数テーブルを更新すると、何が起きますか。