Операции NHibernate не совпадают с транзакциями БД; структура не имеет возможности узнать, какие объекты или какие данные влияет на ваш ExecuteUpdate
, и, следовательно, автоматически не очищает сеанс между SaveOrUpdate
(который может быть отложен в зависимости от FlushMode
сеанса) и CreateSQLQuery
(который всегда является непосредственным, если вы используете ExecuteUpdate
).
Вообще говоря, если вы комбинируя NHibernate логику с логикой низкого уровня SQL (хранимые процедуры и т.д.), то вы будете хотеть использовать TransactionScope
для того, чтобы гарантировать атомарность:
using (var tsc = new TransactionScope())
using (var session = sessionFactory.OpenStatelessSession())
using (var transaction = session.BeginTransaction())
{
session.SaveOrUpdate(entity);
session.Flush();
session.CreateSQLQuery("EXEC foo").ExecuteUpdate();
transaction.Commit();
tsc.Complete();
}
(FWIW - строго говоря, транзакция NHibernate здесь не нужна, так как вы действительно ничего не делаете с сеансом после Flush
, но это хорошая практика использовать явную транзакцию NH в любом случае в случае изменения логики в будущем.)
Обратите внимание, что я предпочитаю использовать IStatelessSession
экземпляров для любые вставки/обновления пакета/etc. - если вы используете обычные экземпляры ISession
и вам нужно действительно получать обновления, сделанные ExecuteUpdate
, вам, возможно, потребуется использовать методы сеанса Evict
или Clear
, чтобы гарантировать получение обновлений.