Skip to content

トランザクション設計 ― 外部APIをトランザクション内で呼んだら?

📖この章のキーワード
用語意味なぜ重要か
トランザクション複数の DB 操作をまとめて成功/失敗させる仕組み部分的な更新を防ぐ
ロックトランザクション中に他のクエリがアクセスできないようにすること保持時間が長いと他の処理がブロックされる
ロールバックトランザクション内の変更を全て取り消すことDB 操作のみ対象。メール等は戻せない
ACIDトランザクションの 4 特性(原子性、一貫性、分離性、永続性)データの信頼性を保証する

Phase 1: 観察

良い例と悪い例を比較します。

php
// ❌ アンチパターン: トランザクション内で外部API
DB::transaction(function () use ($order) {
    $order->update(['status' => 'confirmed']);

    // 外部API呼び出し(3秒かかる)
    Http::post('https://payment.example.com/charge', [...]);
    // ↑ この間、order テーブルのロックが保持される

    // メール送信
    Mail::to($order->user)->send(new OrderConfirmed($order));
    // ↑ もしここで例外 → ロールバック。でもメールは送信済み
});
php
// ✅ 良い例: トランザクションはDB操作のみ
// ExternalEventService::accept() の設計思想
DB::transaction(function () {
    $operation = PartnerOperation::create([...]);
    $receipt = ExternalEventReceipt::create([...]);
    // DB操作のみ → ロックは最短
});

// トランザクション外でJob dispatch
ProcessExternalEventJob::dispatch($receipt->id);

Phase 2: 判断

AI禁止ゾーン
  • トランザクション内で 外部 API を呼ぶ と、何が起きますか?(API が 10 秒応答しない場合)
  • トランザクション内で メールを送信 し、その後に 例外が発生 したら何が起きますか?
  • トランザクションの 範囲 はどう決めるべきですか?

AIに聞く前に、自分の頭で考えてみましょう。

テキストを入力すると有効になります