NHibernate ISession Flush: где и когда его использовать, и почему?



одна из вещей, которые меня полностью смущают, - это использование session.Flush,совместно с session.Commit и session.Close.



иногда session.Close работает, например, он фиксирует все изменения, которые мне нужны. Я знаю, что мне нужно использовать commit, когда у меня есть транзакция или единица работы с несколькими созданиями/обновлениями/удалениями, чтобы я мог выбрать откат, если произойдет ошибка.



но иногда меня действительно загоняет в тупик логикаsession.Flush. Я видел примеры, когда вы есть session.SaveOrUpdate() затем следует флеш, но когда я удаляю флеш, он все равно работает нормально. Иногда я сталкиваюсь с ошибками в инструкции Flush, в которой говорится, что сеанс истек, и удаление его убедилось, что я не столкнулся с этой ошибкой.



есть ли у кого-нибудь хорошие рекомендации относительно того, где и когда использовать флеш? Я проверил документацию NHibernate для этого, но я все еще не могу найти простой ответ.

748   4  

4 ответов:

кратко:

  1. всегда использовать операции
  2. не используйте Close(), вместо этого оберните ваши звонки на ISession внутри using заявление или управление жизненным циклом вашего ISession где-то еще.

С документация:

времени ISession выполнит инструкции SQL, необходимые для синхронизации ADO.NET состояние соединения с состоянием объектов держится в памяти. Этот процесс, flush, происходит по умолчанию в следующих точках

  • от некоторых вызовов Find() или Enumerable()
  • С NHibernate.ITransaction.Commit()
  • С ISession.Flush()

инструкции SQL выдаются в следующем порядке

  1. все вставки сущностей, в том же порядке соответствующие объекты были сохранены с помощью ISession.Save()
  2. все обновления лица
  3. все удаления коллекции
  4. все удаления, обновления и вставки элементов коллекции
  5. все коллекции вставки
  6. все удаления сущностей, в том же порядке соответствующие объекты были удалены с помощью ISession.Delete()

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

кроме тех случаев, когда вы эксплицитность Flush(), нет абсолютно никаких гарантий о том, когда сеанс выполняет ADO.NET звонки, только в том порядке, в котором они выполняются. Тем не менее, NHibernate гарантирует, что ISession.Find(..) методы никогда не вернут устаревшие данные; и они не вернут неправильные данные.

можно изменить поведение по умолчанию, чтобы сброс происходил реже. Элемент FlushMode класс определяет три различных режима: только флеш во время фиксации (и только когда NHibernate ITransaction API используется), флеш автоматически с помощью объясненная процедура, или никогда не смывать, если Flush() вызывается явно. Последний режим полезен для длительно работающих единиц работы, где ISession остается открытым и отключенным в течение длительного времени.

...

Смотрите также в этом разделе:

завершение сеанса включает в себя четыре различных этапа:

  • очистить сессии
  • совершение сделки
  • закрыть сессия
  • обработка исключений

промывка сессии

если вы случайно используете ITransaction API, вам не нужно беспокоиться об этом шаге. Он будет выполняться неявно при фиксации транзакции. В противном случае вы должны позвонить ISession.Flush() для обеспечения синхронизации всех изменений с базой данных.

фиксация транзакции базы данных

если вы используете NHibernate ITRANSACTION API, это выглядит так:

tx.Commit(); // flush the session and commit the transaction

если вы управляете ADO.NET транзакции сами вы должны вручную Commit() ADO.NET сделка.

sess.Flush();
currentTransaction.Commit();

если вы решили не фиксировать свои изменения:

tx.Rollback();  // rollback the transaction

или:

currentTransaction.Rollback();

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

закрытие ISession

вызов ISession.Close() обозначает конец сеанса. Основное значение Close() заключается в том, что ADO.NET соединение будет прервано сеансом.

tx.Commit();
sess.Close();

sess.Flush();
currentTransaction.Commit();
sess.Close();

если вы предоставили свои связи, Close() возвращает ссылку на него, так что вы можете вручную закрыть его или вернуть его в пул. В противном случае Close() возвращает его в пул.

начиная с NHibernate 2.0, транзакции необходимы для операций с БД. Таким образом,ITransaction.Commit() вызов будет обрабатывать любые необходимые промывки. Если по какой-то причине вы не используете транзакции NHibernate, то не будет автоматической промывки сеанса.

время от времени ISession будет выполнять инструкции SQL, необходимые для синхронизации ADO.NET состояние соединения с состоянием объектов, хранящихся в памяти.

и всегда использовать

 using (var transaction = session.BeginTransaction())
 {
     transaction.Commit();
 }

после того, как изменения будут зафиксированы, чем эти изменения, чтобы сохранить в базе данных мы используем транзакцию.Commit ();

вот два примера моего кода, где он потерпел бы неудачу без сеанса.Flush ():

http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html

в конце этого вы можете увидеть раздел кода, где я устанавливаю Identity insert on, сохраняю объект, затем сбрасываю, а затем устанавливаю Identity insert off. Без этого Флеша он, казалось, устанавливал Identity insert и выключал, а затем сохранял сущность.

польза притока() мне дали больше контроля над тем, что происходит.

вот еще один пример:

отправка сообщения NServiceBus внутри TransactionScope

Я не совсем понимаю, почему на этом, но Flush () предотвратил мою ошибку.

Comments

    Ничего не найдено.