Каким должно быть время жизни сеанса NHibernate?

Я новичок в NHibernate и заметил некоторые проблемы при преждевременном закрытии сессий. Я временно решил эту проблему, повторно используя сеансы вместо того, чтобы открывать сеанс для каждой транзакции. Однако у меня сложилось впечатление, что открытие сеансов каждый раз, когда они вам нужны, было рекомендуемым подходом для управления временем существования сеанса. Нет?

Так; каков рекомендуемый способ обработки сессий? Какой должна быть их жизнь? Транзакция PR за одну сессию? Один сеанс singleton для обработки всего? Или что?

Изменить:

Обратите внимание, что архитектура моего приложения представляет собой настольное приложение, взаимодействующее со службой на стороне сервера, что и выполняет всю обработку базы данных с помощью NHibernate + Fluent. (Если это имеет значение ...)


person stiank81    schedule 06.01.2010    source источник
comment
В вашем вопросе stackoverflow.com/questions/2011950/ вы просили меня изучить этот новый вопрос, но я вижу, что вы уже получили достаточное освещение. Я разделяю некоторые мнения здесь, но имейте в виду, что кажется, что сеансы и транзакции перемешаны в обсуждении, хотя это разные вещи. Кроме того, пул сеансов или сеанс, запускаемый по таймауту, могут быть полезными с точки зрения производительности, но их сложно настроить и получить правильно. Также обратите внимание, что под капотом пул соединений используется независимо от выбранного вами шаблона.   -  person Abel    schedule 07.01.2010
comment
Спасибо за комментарий, Абель. В примерах я видел, что сеансы и транзакции часто имеют одно и то же время жизни, но, как видно из упомянутого вопроса, иногда это может быть проблемой ... Я надеюсь, что люди ответили на время жизни сеанса, а не на время жизни транзакции, и у меня сложилось впечатление, что это это так.   -  person stiank81    schedule 07.01.2010


Ответы (5)


Вам нужна стратегия управления сеансом, которая позволяет вашему приложению эффективно функционировать и использовать преимущества NHibernate, в частности кеширование и отложенную загрузку.

Создание сеансов - недорогой процесс и требует небольшого количества предварительной оперативной памяти или процессора, поэтому вам не следует беспокоиться о сохранении или повторном использовании сеансов (действительно, их повторное использование может привести к неприятным и непредвиденным побочным эффектам). Фабрика сеансов - дорогостоящая вещь, и ее следует создавать один и только один раз при запуске приложения.

Эмпирическое правило таково: время жизни сеанса должно быть достаточно длинным, чтобы у вас не было постоянных объектов, оставшихся в области видимости после завершения сеанса.

После завершения сеанса все отслеживание изменений для объектов, которые вы получили из этого сеанса, прекращается, поэтому эти изменения не сохраняются, если вы не намеренно повторно присоедините этот объект к новому сеансу. Таким образом, сеанс должен существовать до тех пор, пока будут существовать извлеченные из него объекты. В веб-приложении это обычно означает сеанс для каждого запроса; в WinForms - сеанс для каждой формы.

В вашем случае со службой (я предполагаю, что она работает как служба Windows), выполняющей работу NHibernate, вы можете рассмотреть возможность создания сеанса для каждого нового запроса от потребляющего настольного приложения и удаления это когда этот запрос был обслужен. Не зная точно, как работает ваша служба и какой механизм использует настольное приложение для взаимодействия с ней (удаленное взаимодействие? WCF? Обычный старый SOAP?), Я не могу быть более конкретным.

(Есть некоторые исключения из этого общего правила - предположим, что у вас есть набор постоянных объектов, которые представляют собой общий ресурс, на который будет ссылаться другой код, но не измениться, вы можете загрузить их заранее при запуске приложения и оставить их отключенными оттуда. на.)

Если вы обнаружите, что производительность при такой стратегии низкая, возможно, вы слишком много общаетесь с базой данных и ваш граф объектов сложен; в этом случае посмотрите на кэширование второго уровня.

person Neil Hewitt    schedule 06.01.2010
comment
Спасибо! Что касается моей службы, я использую WCF, в настоящее время с мылом, работающий как консольное приложение, но я не думаю, что это должно иметь какое-либо значение, поэтому вы были достаточно конкретны. Кажется разумным иметь один сеанс для каждого запроса. В настоящее время я использую только сеанс, в котором выполняется транзакция, и, похоже, есть некоторые данные, на которые есть ссылки, которые не загружаются во время транзакции, которая не выполняется из-за закрытия сеанса. - person stiank81; 06.01.2010

В веб-приложении у вас должен быть один сеанс для каждого запроса. Это дает вам полный контроль над временем существования сеанса и упрощает обработку ошибок.

В настольном приложении я рекомендую использовать сеанс для каждого докладчика (или форму, если хотите). Чтобы процитировать Айенде в его статье в журнале MSDN:

Рекомендуемая практика для настольных приложений - использовать сеанс для каждой формы, чтобы каждая форма в приложении имела свой собственный сеанс. Каждая форма обычно представляет собой отдельную часть работы, которую пользователь хотел бы выполнить, поэтому сопоставление времени жизни сеанса и времени существования формы на практике работает довольно хорошо. Дополнительным преимуществом является то, что у вас больше нет проблем с утечками памяти, потому что, когда вы закрываете форму в приложении, вы также удаляете сеанс. Это сделает все объекты, загруженные в ходе сеанса, пригодными для восстановления сборщиком мусора (GC).

Есть дополнительные причины для предпочтения одного сеанса в форме. Вы можете воспользоваться функцией отслеживания изменений NHibernate, чтобы она сбрасывала все изменения в базу данных при фиксации транзакции. Он также создает изолирующий барьер между различными формами, поэтому вы можете фиксировать изменения в одной сущности, не беспокоясь об изменениях в других сущностях, которые отображаются в других формах.

person R. Martinho Fernandes    schedule 06.01.2010
comment
сеанс на операцию довольно расплывчатый. Вы должны указать сеанс для каждого запроса - person Mauricio Scheffer; 06.01.2010

Сеанс должен соответствовать единице работы. Сеанс должен оставаться активным, пока вы работаете с объектами, извлеченными или сохраненными с помощью этого сеанса.

person David M    schedule 06.01.2010

Не существует одного ответа, подходящего для всех ситуаций. Сессия 13 Summer of Nhibernate представляет хороший обзор проблемы.

person kgiannakakis    schedule 06.01.2010