Skip to main content

第04章:部:同時実行と“二重実行防止”(15〜17章)⚔️🧵

この章のゴール🎯✨

  • 「ここは冪等性が必須🔥」をサクッと判断できるようになる
  • 自分のAPI(仮)を見て「危ない操作」をチェックできる✅
  • “ランキング”の理由を「事故の絵」が浮かぶレベルで説明できるようになる🖼️💡

Concept


まず結論:冪等性が必要かは「二重実行で困るか?」だけ😆🔁

冪等性が必要なのは、だいたい次の2条件がそろうところ👇

  1. 二重実行すると被害がデカい(お金・在庫・権限・ポイント…)💥
  2. 二重実行が起きやすい(タイムアウト・再送・リトライ・並列)🌧️📨

ちなみに、ネットワークやクラウドの世界では「失敗したら再試行」は普通で、“同じリクエストがもう一回飛んでくる”前提で設計するのが現実的です☁️🔁(例:Cloud Storage でも「リトライの安全性=べき等性」が強調されています) (Google Cloud Documentation)


冪等必須度の決め方:超かんたんスコア法📊✨

2つの軸で点数をつけるだけ!

  • 被害の大きさ(Impact):1〜5
  • 再送・重複の起きやすさ(Retry likelihood):1〜5

合計でざっくり判断👇

  • 8〜10:冪等 “必須”🔥
  • 6〜7:強く推奨💪
  • 〜5:状況次第🤔

補足:HTTP的には、PUT/DELETE(+安全なメソッド)は「同じのを何回やっても結果が同じ」=冪等になりやすいと定義されています。 (RFCエディタ) ただし実務では「POSTでも冪等にしたい」場面が山ほどあるので、Idempotency-Keyが出てきます🔑(IETF でヘッダー仕様の標準化も進行中) (greenbytes.de)


冪等性が必要な操作ランキング🏆😆(トップ10)

ここでは「一般的なWebサービス」を想定してるよ🧁🌸 ※「必須度」はだいたいの目安。あなたのサービスで変わります🙆‍♀️


🥇1位:決済・課金・送金(チャージする系)💳🔥

  • 二重実行の事故:二重課金😱(一撃で炎上しがち)

  • なぜ起きる?:決済APIは通信失敗・タイムアウトが起きうる→再送されやすい🔁

  • 対策の王道Idempotency-Keyで「同じキーなら同じ結果を返す」🔑📦

    • Stripe なども「リトライに備えて冪等キーを使う」前提の設計を強く推しています (Stripe)

必須度:10/10🔥🔥🔥


🥈2位:注文確定・予約確定(席/宿/チケット/注文)🧾🎫🔥

  • 事故:同じ注文が2つ作られる/席が2重に確保される😵

  • 対策

    • (注文番号や)冪等キー+ユニーク制約で“物理的に2つ作れない”🗄️🛡️
    • “確定”は状態遷移(pending→confirmed)で守るのも強い🔁

必須度:9/10🔥🔥🔥


🥉3位:在庫引き当て・在庫減算📦⚔️🔥

  • 事故:在庫がマイナス/売り越し😇

  • 対策

    • 在庫は同時実行が多いので、ロックや原子的更新(Atomic)も絡みやすい🔒⚡
    • 「注文ID(or 冪等キー)単位で一回だけ減らす」設計にする✅

必須度:9/10🔥🔥🔥


4位:クーポン消費・ポイント付与/消費🎫⭐🔥

  • 事故:ポイント二重付与=地味に致命傷💸

  • 対策

    • (userId, operationId) のユニーク制約で“同じ付与を二回できない”🛡️
    • 付与・消費は「台帳(ledger)」形式にすると監査もしやすい📒👀

必須度:8/10🔥🔥


5位:権限変更(管理者付与・BAN・ロール更新)🔐🚨

  • 事故:意図しない権限が付いたまま/解除されない😱

  • 対策

    • 「付与」より “状態をこうする” 方式(PUT的)に寄せると冪等にしやすい🔁
    • 監査ログ必須になりがち📝👀

必須度:8/10🔥🔥


6位:外部連携のWebhook受信→処理(配送通知、決済通知など)📩🔁🔥

  • 事故:同じイベントで二重処理(ステータス二重更新、メール二重送信)😵

  • なぜ起きる?:イベント駆動は「少なくとも1回配送(重複あり)」になりやすい世界観😇

  • 対策

    • eventIdの重複排除(Dedup) を最初にやる🧾✅
    • “処理済みeventId” を保存して弾く📦

必須度:8/10🔥🔥


7位:メール/Push通知送信📧📱💥

  • 事故:同じ通知が2回届く(信頼が削れる)🥲

  • 対策

    • 「通知を送ったか」をIDで記録して二重送信防止🧾
    • 重要通知は特に守る(パスワード変更、決済完了など)🔐

必須度:7/10💪


8位:ファイルアップロード完了・変換開始(動画変換など)📁🎬

  • 事故:同じ変換ジョブが2つ走ってコスト増💸

  • 対策

    • “同じファイルhash + 目的” でジョブをユニーク化する
    • 先にジョブ作って「すでにあるならそれを返す」方式📦

必須度:6〜7/10💪


9位:ユーザー登録・アカウント作成👤🧁

  • 事故:アカウントが二重作成(同じメールで2個…)😵

  • 対策

    • メールアドレスのユニーク制約は基本🛡️
    • 作成系は「requestId を付けて冪等性を保証する」設計指針もあります(Google の AIP) (google.aip.dev)

必須度:6/10🤔(サービス次第)


10位:ログ・分析イベント(計測)📈🙂

  • 事故:二重計測で数字がズレる(でも致命じゃないことも多い)

  • 対策

    • 厳密にやるなら eventId で重複排除
    • ただし「多少の重複は許容」も現実的(要件次第)🙆‍♀️

必須度:3〜5/10🙂


よくある“勘違い”注意⚠️😆

「参照だから安全でしょ?」→ 参照でも外部に副作用があると危ない👀💥

例:

  • GETなのに「アクセスしたらポイント付与」みたいな挙動 → それ、実質「更新」なので冪等設計が必要になりやすい😇

「SDKがリトライしてくれるからOK」→ だからこそ冪等が必要🔁

AWSはEC2 APIなどでclient token による冪等性を推していて、「同じトークンは再利用しないでね」も明記されています (AWS ドキュメント) (=“同じ操作の再送は起きる”前提ってことだよね🧠)


📝演習:ミニ注文APIで「冪等必須ポイント」を洗い出そう🔍✨

想定エンドポイント(例)

  • POST /orders(注文作成)🧾
  • POST /payments/confirm(支払い確定)💳
  • POST /orders/{id}/cancel(キャンセル)🧯
  • POST /notifications(通知送信)📩

Step1:表を作る📋

操作Impact(1-5)Retry(1-5)合計判定
注文作成
支払い確定
キャンセル
通知送信

Step2:判定を書く✍️

  • 合計8以上 → 冪等必須🔥(冪等キー or ユニーク制約 or 両方)
  • 合計6-7 → 強く推奨💪
  • 〜5 → 状況次第🤔

🤖AI活用:ランキング判定を“補助輪”にするプロンプト例🔧✨

(そのまま貼ってOK!)

  • 「次の操作一覧を、Impact(1-5) と Retry(1-5) で採点して、理由も1行ずつ書いて」📝
  • 「二重実行したときの最悪事故を、ユーザー視点で具体例にして」😱
  • 「冪等にする手段を、(冪等キー / ユニーク制約 / 状態遷移) のどれが向くかで分類して」🔑🗄️🔁
  • 「“冪等じゃなくてOK”なケースを、前提条件つきで3つ挙げて」🙆‍♀️

ミニクイズ🎮🌸(理解チェック)

Q1:二重実行が一番ヤバいのはどれ?🔥

A) ログ送信 B) 決済 C) 一覧取得 → 答え:B💳(二重課金が直撃)

Q2:「POSTは危ない」けど、冪等にできる?🔁

できる! Idempotency-Key で POST/PATCH を“再送に強くする”考え方が標準化の流れでもあります🔑 (greenbytes.de)


まとめ🌟

  • 冪等必須かは Impact × Retry で決める📊
  • トップ層(決済・確定・在庫・ポイント)は だいたい必須🔥
  • 現代のクラウド運用は「リトライ前提」だから、重複は“起きるもの”として守るのが勝ち筋🔁☁️ (Google Cloud Documentation)