Какой должна быть продолжительность сеанса NHibernate? - PullRequest
41 голосов
/ 06 января 2010

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

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

Edit:

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

Ответы [ 5 ]

26 голосов
/ 06 января 2010

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

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

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

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

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

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

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

11 голосов
/ 06 января 2010

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

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

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

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

6 голосов
/ 06 января 2010

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

2 голосов
/ 06 января 2010

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

0 голосов
/ 06 января 2010

Большая часть инфраструктуры NHibernate и Microsoft ADO.NET Entity Framework схожи. Вот очень хорошая статья о том, как вы должны управлять каналом жизни ObjectContext в ADO.NET EF.

http://blogs.msdn.com/alexj/archive/2009/05/07/tip-18-how-to-decide-on-a-lifetime-for-your-objectcontext.aspx

Это относится и к сессиям NHibernate.

...