26

Webページのボタンをクリックして送信リクエストを開始するとします。次に、提供したデータの一部が間違っていることに突然気付き、それが送信されると、望ましくない結果に直面することになります(この誤ったリクエストの支払いを余儀なくされる可能性のあるショッピングリクエストなど)。

だから私は必死に停止ボタンを1回だけでなく何度もクリックします(念のため)。

そのようなシナリオではどうなりますか?ブラウザはサーバーに通知せずにリクエストをキャンセルするだけですか?サーバーに通知する場合、サーバーはプロセスを強制終了するだけですか、それともこのリクエストの一部として実行されたすべてのアクションのロールバックも実行しますか?

私はJavaでコーディングします。Javaには、STOP要求を検出し、このトランザクションの一部として行ったことをロールバックするために使用できる特別な機能がありますか?

4

5 に答える 5

22

ブラウザからのWebページのロードは、通常4ステップのプロセスです(リダイレクトは考慮されていません)。

  1. サーバーが利用可能になると、ブラウザはHTTPリクエストを送信します
  2. サーバーはコードを実行します(動的ページの場合)
  3. サーバーはHTTP応答(通常はHTML)を送信します
  4. ブラウザはHTMLをレンダリングし、他のファイル(画像、css、...)を要求します

「停止」に対するブラウザの反応は、その時点でのリクエストのステップによって異なります。

  • サーバーが低速または過負荷で、手順1で「停止」を押した場合、何も起こりません。ブラウザはリクエストを送信しません。
  • ただし、ほとんどの場合、ステップ2、3、および4で「停止」がヒットし、これらのステップでコードがすでに実行されている場合、ブラウザーは応答の待機(2)または応答の受信(3)を停止します。 、または応答のレンダリング(4)。

HTTP呼び出し自体は常に2ステップのアクション(要求/応答)であり、クライアントから実行をロールバックする自動方法はありません。

于 2008-09-26T07:34:24.033 に答える
12

この質問は、Java を使用していない人の注意を引く可能性があるため、この質問に関して PHP の動作について言及することにしました。非常に驚くべきことです。

PHP は、クライアントへの接続のステータスを内部的に維持します。可能な値は、NORMAL、ABORTED、および TIMEOUT です。接続ステータスが NORMAL の間は問題なく動作し、スクリプトは引き続き期待どおりに実行されます。

ユーザーがブラウザの [停止] ボタンをクリックすると、通常、クライアントによって接続が閉じられ、ステータスが ABORTED に変わります。ステータスが ABORTED に変わると、実行中のスクリプトの実行がすぐに終了します。余談ですが、ステータスが TIMEOUT に変わった場合 (スクリプトの許容実行時間に対する PHP の設定を超えた場合) にも同じことが起こります。

この動作は特定の状況では役立つ場合がありますが、問題が発生する可能性がある状況もあります。適切な GET リクエスト中はいつでも中止しても安全であるように思われます。ただし、サーバーで変更を行うリクエストの途中で中止すると、変更が部分的にしか完了しない可能性があります。

PHP マニュアルの接続処理に関するエントリを参照して、この動作による複雑さを回避する方法を確認してください。

http://www.php.net/manual/en/features.connection-handling.php

于 2010-03-23T14:47:24.867 に答える
3

一般的に、サーバーはユーザーが停止したことを認識せず、サーバー側のプロセスが完了します。サーバーが応答データをクライアントに返送しようとした時点で、接続が閉じられたためにエラーが表示される場合がありますが、同様に表示されない場合もあります取得できないのは、サーバースレッドが突然中断されることです。

さまざまな複雑なメカニズムを使用してこれを軽減できます。たとえば、送信者が「まだ待機中」と言うajax呼び出しをサーバーに頻繁に送信し、サーバーにこれらの呼び出しをチェックする新しいスレッドで処理を実行させることができますが、それは解決しません。問題を完全に。

于 2008-09-26T07:20:32.053 に答える
1

クライアントはすぐにデータの送信を停止し、接続を閉じます。10回のうち9回は、リクエストがすでに通過しています(おそらく、OSバッファがサーバーに「フラッシュ」されているため)。リクエストを停止したことを通知する追加情報はサーバーに送信されません。

于 2008-09-26T07:22:45.777 に答える
0

重要なシナリオでの送信には、2つの段階が必要です。確認して送信します。ただし、最終的な送信が行われた場合は、トランザクションをコミットします。ユーザーがコミット後にアクションを元に戻すことを許可する以外に、この状況を回避する他の方法を本当に考えることはできません。たとえば、注文の例では、注文が完了した後、顧客が気が変わって、まだ出荷されていない場合に注文をキャンセルできるようにします。もちろん、それをサポートするために書く必要のある余分なコード。

于 2008-09-26T07:25:25.007 に答える