NHibernate ExecuteUpdate不参与当前事务?

我的代码看起来像这样:

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

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

最佳答案
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实例用于任何批量插入/更新/等. – 如果您使用常规ISession实例并且需要实际检索ExecuteUpdate所做的更新,那么您可能需要使用会话的Evict或Clear方法来保证获取更新.

转载注明原文:NHibernate ExecuteUpdate不参与当前事务? - 代码日志