Skip to content

冪等性 ― 同じリクエストが2回来たら

📖この章のキーワード
用語意味なぜ重要か
冪等性(Idempotency)同じ操作を何度やっても結果が変わらないこと再送・リトライで二重処理を防ぐ
リプレイ同じリクエストに対して同じ応答を返すこと安全な再送応答
409 Conflict同じ ID で異なる内容のリクエストを拒否意図しない上書きを防ぐ
lockForUpdate()SELECT 時に行ロックを取得する DB 操作レースコンディション防止
request_hashリクエスト内容のハッシュ値リプレイと衝突を区別する手段

Phase 1: 観察

Chapter 4.2 で見た ExternalEventService::accept() をもう一度、冪等性の観点で読みます。

php
// ExternalEventService.php(冪等性チェック部分)
// Label: exemplar

return DB::transaction(function () use ($integration, $externalEventId, $requestHash) {
    // 排他ロック付きで既存レシートを検索
    $existing = ExternalEventReceipt
        ::where('partner_integration_id', $integration->id)
        ->where('external_event_id', $externalEventId)
        ->lockForUpdate()
        ->first();

    if ($existing) {
        // 同じハッシュ → リプレイ(安全に再応答)
        if ($existing->request_hash === $requestHash) {
            return ['receipt' => $existing, 'replay' => true];
        }
        // 異なるハッシュ → 409 Conflict
        throw new IdempotencyConflictException('...');
    }

    // 新規作成 + dispatch
    // ...
});
条件対応
同じ ID + 同じ内容リプレイ応答(再処理しない)
同じ ID + 異なる内容409 Conflict(拒否)
新しい ID通常処理

Phase 2: 判断

AI禁止ゾーン
  • 冪等性チェックを外したら、同じイベントが 2 回送られた場合に何が起きますか?
  • lockForUpdate()外したら、2 つのリクエストが同時に来た場合に何が起きますか?
  • request_hash の比較は なぜ必要 ですか? ID の一致だけでは不十分ですか?

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

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