web-dev-qa-db-ja.com

ユーザーが支払いに行くが、価格がリクエストの途中で変更されるシナリオを緩和するにはどうすればよいですか?

これは Two Generals 'Problem に似ていますが、完全ではありません。名前はあると思いますが、今は思い出せません。

私は自分のウェブサイトの支払いフローに取り組んでいます。

シナリオ

  1. アリスはボブにサービス料を支払いたいと考えています。ボブは彼女の10ドルを引用した。
  2. アリスは支払いをクリックします。
  3. アリスの要求がエーテルを通って飛んでいる間、ボブは彼の引用を編集します。彼は今、20ドルを望んでいます。
  4. ボブのリクエストは、アリスがサーバーに到達する前に終了します。
  5. アリスのリクエストはサーバーに到達し、彼女の支払いは10ドルではなく20ドルで承認されます。
  6. アリスは不幸です。

これの可能性は実際には非常に低いですが、それは可能なシナリオです。ネットワークの問題などが原因でリクエストがハングすることがあります...

可能な軽減策

この問題は解決できるとは思いません。しかし、それを軽減するために何かをすることができます。

これは厳密にべき等の問題ではないため、答えは「べき等性トークン」ではないと思います。

オプション1

定義しましょう:

  • t_0は、アリスが支払いを支払う時間です。
  • t_editボブの編集リクエストが成功したとき
  • t_1アリスのリクエストがサーバーに到達したとき

t_0は、リクエストデータの一部として送信しない限りおよびクライアントの送信内容を信頼できないため、知ることができないため、t_0は無視します。 。

アリスのリクエストがサーバーに到着したときに、次のことを確認します。

if t_1 - t_edit < 1 minute: return "409 Conflict"(またはその他のコード)

このアプローチは機能しますか? 1 minuteは任意の選択であり、問​​題を完全に解決するわけではありません。アリスの要求がサーバーに到達するまでに1分以上かかる場合、問題は解決しません。

これは対処すべき非常に一般的な問題であるに違いありませんか?

64
turnip

ほとんどの場合、ショッピングカートという中間ステップがあることに注意してください。アイテムを購入するのではなく、ショッピングカートに入れます。間違った瞬間に価格の変更がある場合は、payを押す前にそれを確認できます。支払うときは、ショッピングカートを購入します。その中の商品にはすでに価格が添付されています。

より完全なソリューションとして、価格を読み取り専用にすることができます。ボブがウィジェットの価格を$ 20に上げたとき、彼は本当に$ 20の新しいタイプのウィジェットを作成しましたが、$ 10ウィジェットはまだ存在していますが、アイテムIDがわからない場合は見つかりません。アリスは10ドルのバージョンを購入しようとしています。トランザクションは10ドルで完了します。

0
Loren Pechtel