タイムアウトの後、再送する前に確かめること
外部サービスへ操作を送った直後に通信が切れる。画面は失敗を示していても、相手側では処理が完了していることがあります。ここで同じ操作を送り直すと、注文、送金、通知が二重になる可能性があります。
VEGAの執行・照合では、「成功か失敗か分からない」を独立した状態として扱う設計にしています。内部の記録と相手側の状態を照合し、確認が済むまで再実行を制限します。
設計で決めておくこと
応答が途切れた処理は、相手側の状態を照合するまで無条件に再送しない。
01
「不明」を、失敗とは別の状態にする
明確に拒否された処理と、送信後に応答が失われた処理は、復旧方法が違います。応答不明を失敗として扱うと、自動の再試行で同じ操作を二重に実行してしまうおそれがあります。
表は横にスクロールして確認できます。
| 状態 | 分かっていること | 次の行動 |
|---|---|---|
| 未送信 | 外部操作がまだ始まっていない | 許可と条件を再確認して実行 |
| 受理・完了を確認 | 対象の処理が相手側に記録されている | その結果を記録し、再送しない |
| 明確な拒否 | 相手側が対象の処理を拒否した | 理由に応じて修正または終了 |
| 応答不明 | 相手側の実行状態が確定していない | 照会・照合し、未確定の間は再送を止める |
02
実行前の記録を、復旧の起点にする
処理の識別子、対象、操作内容、許可の根拠を保存してから外部サービスを呼びます。結果を保存する前にアプリが落ちても、「何を確認すべきか」を復元できます。
外部サービスに重複を抑止するキーがある場合は、その仕様と有効期間を確認して使います。キーを付けるだけで一度限りの実行が保証されるとは限りません。照会結果と内部記録の照合も必要です。
外部操作を送る前に保存するもの
- 利用者と対象を含む、一意な処理識別子
- 送信する内容とその版
- 有効な許可と、適用する制約
- 送信開始の状態と時刻
- 相手側の結果を照会するための手掛かり
03
再起動は、途中の処理を確認するところから始める
再起動後に処理を最初からやり直す設計では、途中で送った操作を忘れてしまいます。保存済みの記録から未確定の処理を拾い、外部の状態を照合して、完了・拒否・未確定のどれに当たるかを判定します。
未確定の間に何を止めるかも定めます。同じ対象への追加処理だけを止めるのか、関連する資金や在庫を使う処理も止めるのかは、影響範囲に合わせて決めます。
04
通信が切れる場所を変えて確認する
受け入れ確認では、送信前、送信直後、受理後、結果保存前という異なる場所で処理を中断します。それぞれを再開して、外部作用が重複せず、確認待ちの状態も失われないことを確かめます。
復旧を確かめるシナリオ
- 同じ依頼や通知が二回来る
- 相手側で受理された直後に応答が途切れる
- 受理の応答後、結果保存前にアプリが停止する
- 再起動後も未確定の処理が残っている
- 照会できない間は、危険な再送を行わない
- 照合で分かった結果と、その根拠を記録する
