Appearance
冪等性 ― 同じリクエストが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に聞く前に、自分の頭で考えてみましょう。
テキストを入力すると有効になります