0

Web アプリケーションで同時アクセスをテストしているときに、セッションの動作を追跡するのが困難です。

A、B、C の 3 人のユーザーがいるとします。

これら 3 人のユーザーで 3 つの異なるブラウザーを使用してアプリケーションにログインすると、実行時にユーザー オブジェクトが B から A、または B から C、または C から A に変化しますが、これはランダムに発生します。

私の UserContextHolder クラスは次のとおりです。

public final class UserObjContextHolder {
    private static final ThreadLocal<UserObj> CONTEXT_HOLDER = new ThreadLocal<UserObj>();

    private UserObjContextHolder() {
    }

    public static void setUserObj(UserObj userObj) {
        CONTEXT_HOLDER.set(userObj);
    }

    public static UserObj getUserObj() {
        return CONTEXT_HOLDER.get();
    }

}

ORM と Spring MVC に Hibernate を使用しています

このセッションの動作の理由や同期方法を誰か教えてもらえますか?

ユーザー A がログインして検索操作を行っているときに、ユーザー B が同時にログインすると、userObj A が userObj B に変更されていることに気付きました。

アプリケーションサーバーの設定と関係ありますか?これは、認証を行っているときにのみ発生します。

4

1 に答える 1

2

検索操作をどのように実行したか、どの時点で ThreadLocal オブジェクト (CONTEXT_HOLDER) に UserObj を設定したかについて詳しく知りたいです。

ThreadLocal はスレッドスコープであり、セッション スコープではないことに注意してください。これは、オブジェクトを設定したスレッドがそれを要求したスレッドと同じである場合にのみ、ThreadLocal 内の設定されたオブジェクトが同じであることを意味します。

私の最初の理論では、検索操作は同じセッションで実行されますが、同じスレッドでは実行されません。簡単なシナリオを以下に示します。

  • UserA は Thread A を使用してログインします。UserA は Thread A を使用して CONTEXT_HOLDER に格納されます。
  • UserB は Thread B を使用してログインします。UserB は Thread B を使用して CONTEXT_HOLDER に格納されます。
  • UserC は Thread C を使用してログインします。UserC は Thread C を使用して CONTEXT_HOLDER に格納されます。
  • しばらくして、UserA が検索操作を実行します。サーバーはスレッド A を使用して (幸いにも) 操作を実行します。ThreadLocal は、正しい期待どおりの UserA obj を返します。
  • 再び、しばらくしてユーザAが検索操作を行う。今回は (残念ながら) サーバーはスレッド C を使用して操作を実行します (うーん!)。スレッド C が検索操作の実行に使用されたため、ThreadLocal は UserC を返します。(一方、検索操作で Thread B が使用された場合、UserB は ThreadLocal によって返されます)

上記のシナリオは、サーバーで使用されるスレッドが 3 つだけであると仮定して、単純化しすぎています。しかし、さまざまな UserObj オブジェクトを取得する方法が説明されていることを願っています。上記で説明したことが発生している場合、時々 NULL 値も受け取っていると思います (これが発生する頻度は、サーバーが使用するスレッドの総数によって異なります)。その理由は、ThreadLocal が現在設定されていない場合 (上記のコードに基づいて null である場合)、初期値を返すためです。

したがって、問題の解決策は、同じスレッドで次のことを実行することです。

  • ThreadLocal で UserObj を設定します
  • 検索操作を実行し、ThreadLocal で UserObj を取得する

このサンプル コードを提供したい場合は、お知らせください。

于 2013-01-23T02:55:24.177 に答える