8

これが私のRESTfulWebアプリで起こっていることです:

  1. HTTPリクエストが届きます
  2. アプリは、データの最初の部分を使用して応答の作成を開始します
  3. 別のリクエストにより、ステップ2で使用されたデータが変更されます
  4. 最初のリクエストは、データの有効期限が切れていることを理解しています

それは何をすべきですか?リクエストに失敗し、クライアントにエラーを返しますか?または、最初から開始する必要がありますか(クライアントの予想よりも時間がかかります)?

4

5 に答える 5

4

私見では、RESTリクエストをDBトランザクションの処理方法に非常に近い方法で処理する必要があります。

  • 実際の作業を行う前に、ロックする必要があるものをロックしてください。
  • または、同時実行の問題で失敗/再試行する準備をします

非常に多くの場合、これは実際にDBトランザクションに受け継がれる可能性があります-リクエストが行う非DB作業の量と内容によって異なります。

于 2012-08-21T15:41:24.383 に答える
3

良い出発点は、CouchDBで使用される並行性モデルだと思います。本質的に:

  • 各リクエストは個別に処理されます。つまり、他の同時リクエストの影響を受けません。これは、要求の処理を開始するときにデータベースの一貫したスナップショットを取得できる必要があることを意味します。これは、ほとんどのDBMSシステムがトランザクションの概念でサポートしています。
  • GETリクエストは常に成功し、その後の更新を無視して、送信された時点のシステムの状態を返します。
  • GETリクエストは、問題のリソースのリビジョンIDを返します。これは、後続のPUTリクエストのフィールドとして含める必要があります。
  • PUT要求では、送信されたリビジョンIDがデータベース内の最新のリビジョンIDと照合されます。それらが一致しない場合、エラーコードが返されます。その場合、クライアントは最新バージョンを再フェッチし、行った変更を再適用する必要があります。

もっと読む:

http://wiki.apache.org/couchdb/Technical%20Overview#ACID_Properties http://wiki.apache.org/couchdb/HTTP_Document_API#PUT

于 2012-08-21T16:26:23.640 に答える
2

それがdbトランザクションに関するものではなく、分散型の長時間実行プロセスが各ステップに関与していると仮定します。

このシナリオでは、クライアントに適切な応答(409/410 httpコードなど)を送信し、この要求が無効になったことを示す詳細を送信して、クライアントが再試行する必要があります。再試行するとループが発生したり、最悪の場合、クライアントが知らなかったことを実行したりする可能性があります。

たとえば、ホテル/チケットをオンラインで予約すると、価格が変更されたという応答が返され、新しい価格で購入するには再度送信する必要があります。

于 2012-08-24T20:36:01.430 に答える
1

私の観点からすると、あなたの質問は次のようになります。
「データベースから読み取りを行おうとして、別のトランザクションが書き込みを行おうとすると、ブロックされます。しかし、読み取りを終了すると、読んだ後に入ってくる新しいトランザクションによって入力される新しいデータ。」
これはそれについて考えるのに悪い方法です。クライアントが応答で一貫したデータを取得することを確認する必要があります。データが更新されている場合は、元の方法の問題ではない応答が返されます。
あなたの問題は、データが現在更新されていることです、そして私はたまたま知っています。応答がネットワークから送信された直後にデータが更新された場合はどうなりますか?
IMHOは、要件に合った最もシンプルなソリューションを選択します。
クライアントは、データの最新のコピーを常に持っていることを確認するために、より頻繁に「ポーリング」する必要があります

于 2012-08-21T15:44:15.870 に答える
-1

厳密に言えば、競合状態はバグです。競合状態の解決策は、データを共有することではありません。特定のユースケースでそれを回避しない場合は、先着順であることが通常は役立ちます。

最初のリクエストは共有データをロックし、2番目のリクエストは最初のリクエストが完了するまで待機します。

于 2012-08-21T15:43:30.843 に答える