4

だからここに問題があります。私は、すべてのリポジトリ、ドメイン、およびマッピングファイルを保持する共通のクラスライブラリを持っているので、ライブラリは他のWebビーズアプリケーション内で再利用できます。現在、このクラスライブラリ内には、リポジトリで使用されるセッションファクトリを作成できるようにする一連のコードがあります。コードは次のようになります。

        private static ISessionFactory sessionFactory;
        private static Configuration configuration;

        public static Configuration Configuration()
        {
            if (configuration == null)
            {
                configuration = new Configuration().Configure();
            }
            return configuration;
        }

        private static ISessionFactory SessionFactory
        {
            get
            {
                if (sessionFactory == null)
                {
                    sessionFactory = Configuration().BuildSessionFactory();
                }
                return sessionFactory;
            }
        }

        public static ISession GetCurrentSession()
        {
            if (!CurrentSessionContext.HasBind(SessionFactory))
            {
                CurrentSessionContext.Bind(SessionFactory.OpenSession());
            }
            return SessionFactory.GetCurrentSession();
        }

したがって、リポジトリはGetCurrentSession()メソッドを呼び出してISessionを取得します。これで問題なく動作しますが、スレッドセーフではない可能性があるのではないかと心配しています。誰かが私がそれをスレッドセーフにするのを助けるアプローチで私を助けることができますか?

注意すべき点はほとんどありません。

開始イベント時にWebアプリケーションのglobal.asaxでSessionFactoryを構成および構築することを考えましたが、これに関する問題は、問題の共通クラスライブラリが20の異なるアプリケーション内で使用されるため、すべてのアプリケーションに移動して更新することを意味します。これを行う前に、global.asaxファイルに質問を出して、これについて他の方法があるかどうかを確認したいと思いました。共通クラスライブラリがそのSessionFactory自体を構成し、それでもスレッドセーフになるようにするためです。

この巨大な質問を読んでくれてありがとう。どんな助けでも評価します。

4

4 に答える 4

7

セッションファクトリはスレッドセーフですが、セッションはそうではありません。セッションファクトリの構築は保護する必要があります。

    private static object lockObject = new object();

    private static ISessionFactory SessionFactory
    {
        get
        {
            lock (lockObject)
            {
                if (sessionFactory == null)
                {
                    sessionFactory = Configuration().BuildSessionFactory();
                }
                return sessionFactory;
            }
        }
    }

セッションファクトリは、スレッドが最初にセッションを要求したときに作成されます。セッションファクトリが複数回作成されるのを防ぐために、これはスレッドセーフである必要があります。

セッションファクトリによるセッションの作成はスレッドセーフであるため、それについて心配する必要はありません。

于 2011-09-09T10:39:32.177 に答える
0

NHibernateでは、セッションは設計上スレッドセーフではありません。したがって、1つのスレッドのみが使用するセッションがある限り、問題はありません。スレッドごとに個別のNHibernateセッションがある限り、複数のスレッドに対して1つのNHibernateSessionFactoryを持つことができます。

詳細については、以下のリンクをご覧ください。

https://forum.hibernate.org/viewtopic.php?p=2373236&sid=db537baa5a57e3968abdda5cceec2a24

于 2011-09-09T10:10:06.370 に答える
0

次のように、リクエストごとに1つのセッションを使用することをお勧めします。

public ISession GetCurrentSession()
{
        HttpContext context = HttpContext.Current;

        var currentSession = context.Items["session"] as ISession;

        if( currentSession is null )
        {
             currentSession = SessionFactory.GetCurrentSession()
             context.Items["session"] = currentSession;
        }

        return currentSession;
}
于 2011-09-09T10:11:39.757 に答える
0

Stefan Steineggerのコメントに続いて、ロックの直前にnullチェックを追加する方が効率的だと思います。そうすれば、sessionFactoryがすでに初期化されている場合は、毎回ロックする必要がありません。

private static object lockObject = new object();

private static ISessionFactory SessionFactory
{
    get
    {
        if (sessionFactory != null)
        {
            return sessionFactory;
        }

        lock (lockObject)
        {
            if (sessionFactory == null)
            {
                sessionFactory = Configuration().BuildSessionFactory();
            }
            return sessionFactory;
        }
    }
}
于 2018-08-21T12:46:30.883 に答える