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();
}