NHibernate SessionFactory Потокобезопасный выпуск - PullRequest
4 голосов
/ 09 сентября 2011

Так вот в чем проблема. У меня есть общая библиотека классов, в которой хранятся все репозитории, домены и файлы сопоставлений, поэтому библиотека может быть повторно использована в других веб-приложениях. Теперь в этой библиотеке классов есть фрагмент кода, который позволяет самому создавать фабрику сеансов для использования в своих репозиториях. Код выглядит примерно так.

        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. Теперь это работает нормально, но я беспокоюсь, что это не может быть потокобезопасным. Может ли кто-нибудь помочь мне с подходом, который поможет мне сделать его безопасным.

Несколько замечаний:

Я думал о настройке и построении SessionFactory в global.asax веб-приложений при запуске события, но проблема в том, что общая библиотека классов используется в 20 различных приложениях, так что это будет означать, что все приложения и обновление файла global.asax сейчас, прежде чем я сделаю это, я хотел бы задать вопрос, чтобы посмотреть, есть ли другие способы, которыми я могу пойти по этому поводу. Таким образом, общая библиотека классов может настраивать свою SessionFactory самостоятельно и при этом быть поточно-ориентированной.

Спасибо, что прочитали этот огромный вопрос. Подойдет любая помощь.

Ответы [ 4 ]

7 голосов
/ 09 сентября 2011

Фабрика сеанса является потокобезопасной, а сеанс - нет.Создание фабрики сеансов должно быть защищено:

    private static object lockObject = new object();

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

Фабрика сеансов создается при первом запросе сеанса потоком.Это должно быть поточно-ориентированным, чтобы избежать создания фабрики сеансов несколько раз.

Создание сеанса с помощью фабрики сеансов является поточно-ориентированным, поэтому вам не нужно об этом беспокоиться.

0 голосов
/ 21 августа 2018

Исходя из комментария Стефана Штайнеггера, я думаю, что было бы более эффективно добавить нулевую проверку непосредственно перед блокировкой, таким образом вам не нужно блокировать каждый раз, если 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;
        }
    }
}
0 голосов
/ 09 сентября 2011

Я предлагаю использовать один сеанс для каждого запроса, как это:

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;
}
0 голосов
/ 09 сентября 2011

Сессии не являются поточно-ориентированными в NHibernate.Так что все должно быть в порядке, если у вас сеанс, используемый только одним потоком .У вас может быть один NHibernate SessionFactory для нескольких потоков, если у вас есть отдельный сеанс NHibernate для каждого потока

. Для получения дополнительной информации перейдите по ссылке ниже:

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

...