19

この問題について数時間グーグルで検索しましたが、評価はありませんでした。

WELD ドキュメントと CDI 仕様は、提供されているスコープのスレッド セーフに関して非常に明確です。

例えば:

  • 適用範囲 - 安全ではない

  • セッション スコープ - 安全ではありません

  • Request Scope - 安全で、常に単一のスレッドにバインドされます

  • 会話範囲 - 安全 (WELD プロキシが複数の要求スレッドからのアクセスをシリアル化するため)

JSF 2.x で定義されたビュー スコープで何も見つかりません。

単一のビュー/ユーザーにバインドされているにもかかわらず、複数のリクエストが同時にスコープにヒットする可能性が非常に高いという点で、会話スコープとほぼ同じバケットにあります。私が知らないのは、JSF 実装が複数の要求から Bean へのアクセスをシリアライズするかどうかです。

これを解決できる仕様または Morraja/MyFaces 実装の知識を持っている人はいますか?

4

2 に答える 2

19

ビュー スコープは、通常の使用法でスレッド セーフです。1 つのブラウザー ウィンドウ/タブでのみ使用できます。つまり、最初の GET 要求で設定された固有の隠し入力フィールドによってキーが設定されます。同じビューのすべてのポストバックは、1 つの同じビュー スコープ Bean を使用します。ブラウザー自体は、同じウィンドウ/タブで既にポストバック要求を「同期」しています。新しいブラウザー ウィンドウ/タブは事実上新しい GET 要求であるため、完全に独立した新しいビューが作成されます。

ajax ポストバックに関しては、仕様によりキューに入れられます。これは、 JSF 2 仕様の 13.3.2 章に記載されています。

13.3.2 Ajaxリクエストのキューイング

すべての Ajax リクエストは、サーバーに送信される前にクライアント側のリクエスト キューに入れられ、Ajax リクエストが送信された順序で処理されるようにする必要があります。キューで最も長く待機しているリクエストが、次に送信されるリクエストです。リクエストが送信された後、Ajax リクエスト コールバック関数はキューからリクエストを削除する必要があります (デキューとも呼ばれます)。リクエストが正常に完了した場合は、キューから削除する必要があります。エラーが発生した場合、クライアントに通知する必要がありますが、次の要求を送信できるように、要求をキューから削除する必要があります。次の要求 (キュー内の最も古い要求) を送信する必要があります。jsf.ajax.request Ajax リクエスト キューの詳細については、JavaScript のドキュメントを参照してください。

PrimeFaces を使用する場合のみ、 でキューイングを無効にできます<p:ajax async="true">。これをビュー スコープ Bean と組み合わせて使用​​する場合、セッション スコープ Bean と同じようにスレッド セーフを再検討する必要があります。

以下も参照してください。

于 2011-09-14T03:21:15.290 に答える
4

ViewScopedBean は、 ごとに作成される「ビュー」MapUIViewRootに格納されます。2 つの同時要求が JSF ランタイムによって処理される場合、通常、UIViewRootこれらの要求に対して同じインスタンスが作成/復元される可能性はほとんどありません。これはjavax.faces.ViewState、HTTP 要求のフォーム パラメータを使用して、既存のUIViewRootインスタンスを復元する必要があるかどうかを判断するためです (ポストバック)。BalusC が示しているように、2 つの異なるブラウザー ウィンドウでは、2 つの異なるビュー スコープ Bean が作成されます。これは、基礎となる ViewStates パラメーターが両方のブラウザー タブで異なるためです (2 つの異なる HTTP 要求を発行し、ブラウザーがそれぞれの応答を使用している場合)。キャッシュされたコピーを使用する代わりに、個々のタブを表示します)。

ただし、スレッドセーフに関する部分は、ブラウザーのタブ/ウィンドウを超えています。UIViewRoot2 つの HTTP リクエスト (したがって 2 つのスレッド)javax.faces.ViewStateがコンテナによって処理されるリクエストで同じ値を提示する場合、JSF ランタイム (少なくとも Mojarra 内) 内には、ビュー マップへのアクセスを同期する固有のメカニズムはありません。したがって、ビュー スコープ Bean は本質的にスレッド セーフではなく、スレッド セーフな方法でアクセスされることもありません。これは、同じ値のリクエストをリプレイすることで確認できますjavax.faces.ViewState。コンテナが短期間に複数のそのようなリクエストを受信した場合のコンテナ/JVM の動作を観察できます (その結果、UIViewRoot複数のスレッドが同じインスタンスに同時にアクセスする可能性があります)。

于 2011-09-14T04:27:02.807 に答える