Nhibernate; контроль за сохранением сеанса на запрос - PullRequest
2 голосов
/ 23 сентября 2011

Я пытаюсь разработать приложение веб-форм с использованием NHibernate и модели Session Per Request . Все примеры, которые я видел, имеют HTTPModule, который создает сеанс и транзакцию в начале каждого запроса, а затем фиксирует транзакцию и закрывает сеанс в конце запроса. У меня это работает, но у меня есть некоторые проблемы.

Основная проблема заключается в том, что объекты автоматически сохраняются в базе данных после завершения веб-запроса. Я не особенно доволен этим и предпочел бы более активный подход к решению вопроса о том, что на самом деле сохраняется после завершения запроса. Возможно ли это с подходом Session Per Request?

В идеале я бы хотел, чтобы взаимодействие с базой данных происходило примерно так:

  1. Получить объект из базы данных или создать новый
  2. Измените его каким-либо образом
  3. Вызовите метод сохранения для объекта, который проверяет, действительно ли он готов к передаче в базу данных
  4. Объект сохраняется в базе данных

Я могу сделать это, если я не использую модель Sessions Per Request и заключаю взаимодействия в блоки транзакций using session / using. Проблема, с которой я столкнулся при использовании этого подхода, заключается в том, что после загрузки объекта из базы данных сеанс закрывается, и я не могу использовать отложенную загрузку. В большинстве случаев это нормально, но есть несколько объектов, у которых есть списки других объектов, которые затем не могут быть изменены, поскольку, как указано, сессия была закрыта. Я знаю, что могу охотно загружать эти объекты, но они не всегда привыкают, и я чувствую, что при этом я не могу использовать NHibernate.

Есть ли какой-нибудь способ использовать Session Per Request (или любую другую модель, кажется, что она наиболее распространена), которая позволит мне использовать ленивую загрузку И даст мне возможность вручную решать, когда объект сохранить обратно в базу данных? Любой код, учебные пособия или отзывы с благодарностью.

1 Ответ

3 голосов
/ 23 сентября 2011

Да, это возможно, и вы должны быть в состоянии найти примеры этого. Вот как я это делаю:

  • Использовать сеанс для запроса, но не начинать транзакцию в начале запроса.
  • Установите для ISession.FlushMode значение Commit.
  • При необходимости используйте отдельные транзакции (иногда несколько за сеанс).
  • В конце сеанса выдается исключение, если есть активная незафиксированная транзакция. Если сеанс грязный, очистите его и запишите предупреждение.

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

Имейте в виду, что если вы используете идентификаторы, назначенные базе данных (столбцы идентификаторов в SQL Server), NHibernate может выполнять вставки за пределы ваших транзакций. Конечно, ленивая загрузка может происходить вне транзакций (вы должны использовать транзакции и для чтения).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...