NHibernate ExecuteUpdate不参与当前事务?

NHibernate ExecuteUpdate不参与当前事务?,nhibernate,transactions,Nhibernate,Transactions,我有如下代码: using (var session = this.sessionCreator.OpenSession()) using (var transaction = session.BeginTransaction()) { session.SaveOrUpdate(anObject); session.CreateSQLQuery(sql) .ExecuteUpdate(); transaction.Commit(); } 令人惊讶的是,S

我有如下代码:

using (var session = this.sessionCreator.OpenSession())
using (var transaction = session.BeginTransaction())
{
    session.SaveOrUpdate(anObject);
    session.CreateSQLQuery(sql)
        .ExecuteUpdate();
    transaction.Commit();
}

令人惊讶的是,SQL查询在保存对象之前执行。显然,
ExecuteUpdate
命令不参与当前事务。有没有办法让更新登记到事务中?

NHibernate事务与DB事务不同;框架无法知道您的
执行更新影响哪些实体或哪些数据,因此不会自动刷新
保存或更新
(根据会话的
刷新模式
)和
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事务,因为在
刷新之后,您实际上没有对会话做任何事情,但是最好还是使用显式NH事务,以防将来逻辑发生变化。)


请注意,对于任何批插入/更新等,我更喜欢使用
IStatelessSession
实例。如果您使用的是常规
issession
实例,并且需要实际检索
ExecuteUpdate
所做的更新,那么您可能需要使用会话的
execut
Clear
方法来保证GET正在更新。

我不确定您使用的是哪个版本的NHibernate,但考虑到现在是2年后,您的答案很可能适用于较早的版本。我使用的是3.3.3.GA,NHibernate事务能够管理SQL Query ExecuteUpdate而没有问题。我检查了是否无法查看提交的数据直到我运行transaction.Commit()之后

using (var session = sessionFactory.OpenStatelessSession())
using (var transaction = session.BeginTransaction())
{
    session.SaveOrUpdate(entity);
    session.Flush();
    session.CreateSQLQuery("EXEC foo").ExecuteUpdate();
    transaction.Commit();
}