Время от времени ISession
будет выполняться SQL-операторы, необходимые для синхронизации состояния соединения ADO.NET с состоянием объектов, хранящихся в памяти. Этот процесс, flush, происходит по умолчанию в следующих точках
- от некоторых вызовов
Find()
илиEnumerable()
- из
NHibernate.ITransaction.Commit()
- из
ISession.Flush()
Операторы SQL выдаются в следующем порядке
- все объекты вставки, в том же порядке соответствующие объекты были сохранены с помощью
ISession.Save()
- все обновления сущностей
- все удаления коллекции
- все удаления, обновления и вставки элементов коллекции
- все коллекции вставок
- все удаления объектов, в том же порядке соответствующие объекты были удалены с помощью
ISession.Delete()
(Исключением является то, что объекты, использующие генерацию собственных идентификаторов, вставляются при сохранении.)
За исключением случаев, когда вы работаете с подробностями Flush()
, нет абсолютно никаких гарантий относительно того, когда Session выполняет вызовы ADO.NET, только порядок, в котором они выполняются . Однако NHibernate гарантирует, что ISession.Find(..)
методы никогда не будут возвращать устаревшие данные; и при этом они не будут возвращать неправильные данные.
Можно изменить поведение по умолчанию, чтобы сброс происходил реже. FlushMode
Класс определяет три различных режима: только на одном уровне во время фиксации (и только тогда , когда NHibernate ITransaction
используется API), флеш автоматически с помощью объясняемая рутина, или никогда не вровень , если Flush()
не вызывается явно. Последний режим полезен для длительных единиц работы, где ISession
он остается открытым и отключенным в течение длительного времени.
...
Завершение сеанса включает четыре отдельных этапа:
- очистить сессию
- совершить сделку
- закрыть сессию
- обрабатывать исключения
Промывка сессии
Если вы используете ITransaction
API, вам не нужно беспокоиться об этом шаге. Это будет выполнено неявно, когда транзакция будет зафиксирована. В противном случае вам следует позвонитьISession.Flush()
чтобы убедиться, что все изменения синхронизированы с базой данных.
Фиксация транзакции базы данных
Если вы используете API-интерфейс NHibernate ITransaction, это выглядит следующим образом:
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.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 с состоянием объектов, хранящихся в памяти.
И всегда использую
после того, как изменения будут зафиксированы, чем эти изменения для сохранения в базе данных, мы используем транзакцию.Commit ();
источник
Вот два примера моего кода, где он потерпит неудачу без session.Flush ():
http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html
в конце этого вы можете увидеть фрагмент кода, в котором я установил идентификационную вставку, сохранил сущность, затем сбросил, затем отключил идентификационную вставку. Без этого сброса казалось, что он устанавливает и выключает вставку идентификатора, а затем сохраняет сущность.
Использование Flush () дало мне больше контроля над тем, что происходит.
Вот еще один пример:
Отправка сообщения NServiceBus внутри TransactionScope
Я не совсем понимаю, почему на этом, но Flush () предотвратил мою ошибку.
источник