DEEP GUIDE 06
二重送信と同時送金
通信切断と競合があっても、一件を一件として確定する仕組みを読む。
このガイドで追う一件
送金ボタンを押した直後に通信が切れ、利用者がもう一度押します。同時に逆向きの送金も届いた場合を考えます。
コードを読む順番
以下は MiniBank v1.0.0 の確認先です。マイグレーションは順に適用されるため、関数の最終形を調べるときは後続の変更も確認してください。
- 1
同じ依頼を識別する
TransferService は冪等性キーを execute_transfer に渡します。再試行時には同じ依頼として識別できるキーを保つ必要があります。
確認するファイル
src/services/TransferService.ts - 2
ロックの前後で再確認する
execute_transfer は早い段階で既存の依頼を調べ、口座を決まった順でロックした後にも再確認します。待機中に条件が変わる可能性を扱います。
確認するファイル
supabase/migrations/20260819163038_create_execute_transfer_function.sql - 3
残高の競合を防ぐ
画面で見た残高ではなく、ロック後に帳簿から計算した残高を基準に送金可否を判断します。
確認するファイル
supabase/migrations/20260819163038_create_execute_transfer_function.sql - 4
成立した一件を検証する
送金の回帰テストでは、同じキーの再送、異なる内容でのキー再利用、失敗後の取引行を確かめます。同時実行の安全性はロック順序と再確認のコードを別に読んで判断します。
確認するファイル
scripts/regression/suites/transfer.mjs
失敗時・範囲外の確認
応答が届かなかっただけでは送金の失敗と断定できません。新しいキーで送ると別の依頼になるため、同じキーで結果を確かめ、取引履歴も確認します。
ここまでで説明できること
冪等性、行ロック、トランザクションがそれぞれ別の問題を守ることを説明できます。