本文へ移動

再送したら二重登録?APIの再試行を支える「冪等性」

送信中に通信が切れると、相手が処理を終えたのか分からないことがあります。そこで単純にやり直すと、同じ登録が二度行われるかもしれません。再試行を安全に扱うための冪等性と、同じ依頼を識別する仕組みを紹介します。

返事が届かないことと、処理の失敗は違う

予約を登録するアプリを考えてみます。サーバーでは登録が完了したものの、完了の返事がアプリへ届く前に通信が切れたとします。画面にはエラーが出ても、予約自体は存在します。

この状態で新しい登録として送り直すと、二件目の予約ができる可能性があります。これは説明用の仮例ですが、返事を受け取れなかったときに、送信側だけでは成否を決められない点が問題になります。

AWSの再試行と冪等性の解説でも、再試行による副作用を避けるため、同じ依頼を識別する設計が扱われています。

同じ操作を繰り返しても、結果を増やさない

冪等性は「べきとうせい」と読みます。ここでは、同じ依頼を複数回送っても、一回実行した場合と同じ効果になる性質を指します。

「通知を無効にする」は、すでに無効なら状態を変えずに終えられます。一方、「予約を一件追加する」は、そのまま繰り返せば件数が増えます。追加処理では、同じ予約依頼の再送か、新しい予約かを区別する手掛かりが必要です。

よく使われるのが、操作ごとの識別子である冪等性キーです。一つの予約依頼にキーを付け、通信の再試行では同じキーを使います。受け取る側は、そのキーの処理状況や結果を見て、重複した追加を避けます。

入力内容が同じでも、別の依頼かもしれない

同じ内容だから重複と決めると、別の問題が起きます。たとえば同じ備品を二回に分けて追加する操作は、どちらも利用者が意図したものかもしれません。

前掲のAWSの解説でも、依頼内容だけから重複を推測する方法と、呼び出す側が一意な識別子を渡す方法を区別しています。「同じ入力」と「同じ依頼」を分けることが重要です。

表が見切れる場合は横にスクロールできます

入力内容が同じでも、別の依頼かもしれないの表

起きていること

キーの考え方

返事が届かず、同じ登録を再試行

同じ依頼のキーを保つ

利用者が別の登録を新しく開始

新しい依頼として識別する

同じキーなのに登録内容が違う

意図の不一致として扱う

表は設計の考え方です。キーを送れば、どのAPIでも自動的に重複を防げるわけではありません。受け取るAPIの対応と契約を確かめる必要があります。

キーには、保存期間とエラー時の決まりがある

具体例として、Stripeの冪等なリクエストの仕様は、同じキーによる再試行に、最初に保存したステータスコードと本文を返すと説明しています。成功結果だけでなく、保存されたエラー結果も含まれます。ただし、入力の検証段階で拒否された場合など、実行が始まらず結果を保存しないケースもあります。

同仕様では、キーが少なくとも24時間経過すると削除され得ることや、削除後のキー再利用は新しいリクエストになることも説明されています。この保持条件はStripeの仕様で、すべてのAPIに共通する保証ではありません。

長く時間が空いた場合や、どの段階で失敗したか分からない場合は、再送だけを続けず、登録結果を照会する手段が役立ちます。画面にも「完了」「失敗」「結果を確認中」を区別して伝えられると、利用者が新しい操作を重ねる前に状況を理解しやすくなります。

まとめ

通信の失敗だけでは、相手側の処理が失敗したとは言い切れません。同じ依頼の再試行と新しい操作を識別し、APIごとの保持期間やエラー時の扱いを確認することが、二重処理を避ける土台になります。

出来事を受け取る側での重複の考え方は、Webhookの基本でも紹介しています。