これが私のRESTfulWebアプリで起こっていることです:
- HTTPリクエストが届きます
- アプリは、データの最初の部分を使用して応答の作成を開始します
- 別のリクエストにより、ステップ2で使用されたデータが変更されます
- 最初のリクエストは、データの有効期限が切れていることを理解しています
それは何をすべきですか?リクエストに失敗し、クライアントにエラーを返しますか?または、最初から開始する必要がありますか(クライアントの予想よりも時間がかかります)?
これが私のRESTfulWebアプリで起こっていることです:
それは何をすべきですか?リクエストに失敗し、クライアントにエラーを返しますか?または、最初から開始する必要がありますか(クライアントの予想よりも時間がかかります)?
私見では、RESTリクエストをDBトランザクションの処理方法に非常に近い方法で処理する必要があります。
非常に多くの場合、これは実際にDBトランザクションに受け継がれる可能性があります-リクエストが行う非DB作業の量と内容によって異なります。
良い出発点は、CouchDBで使用される並行性モデルだと思います。本質的に:
もっと読む:
http://wiki.apache.org/couchdb/Technical%20Overview#ACID_Properties http://wiki.apache.org/couchdb/HTTP_Document_API#PUT
それがdbトランザクションに関するものではなく、分散型の長時間実行プロセスが各ステップに関与していると仮定します。
このシナリオでは、クライアントに適切な応答(409/410 httpコードなど)を送信し、この要求が無効になったことを示す詳細を送信して、クライアントが再試行する必要があります。再試行するとループが発生したり、最悪の場合、クライアントが知らなかったことを実行したりする可能性があります。
たとえば、ホテル/チケットをオンラインで予約すると、価格が変更されたという応答が返され、新しい価格で購入するには再度送信する必要があります。
私の観点からすると、あなたの質問は次のようになります。
「データベースから読み取りを行おうとして、別のトランザクションが書き込みを行おうとすると、ブロックされます。しかし、読み取りを終了すると、読んだ後に入ってくる新しいトランザクションによって入力される新しいデータ。」
これはそれについて考えるのに悪い方法です。クライアントが応答で一貫したデータを取得することを確認する必要があります。データが更新されている場合は、元の方法の問題ではない応答が返されます。
あなたの問題は、データが現在更新されていることです、そして私はたまたま知っています。応答がネットワークから送信された直後にデータが更新された場合はどうなりますか?
IMHOは、要件に合った最もシンプルなソリューションを選択します。
クライアントは、データの最新のコピーを常に持っていることを確認するために、より頻繁に「ポーリング」する必要があります
厳密に言えば、競合状態はバグです。競合状態の解決策は、データを共有することではありません。特定のユースケースでそれを回避しない場合は、先着順であることが通常は役立ちます。
最初のリクエストは共有データをロックし、2番目のリクエストは最初のリクエストが完了するまで待機します。