NHibernate ExecuteUpdate不参与当前事务?

bri*_*rns 4 nhibernate transactions

我的代码看起来像这样:

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

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

Aar*_*ght 5

NHibernate事务与数据库事务不同; 框架无法知道您ExecuteUpdate正在影响哪些实体或哪些数据,因此不会自动刷新SaveOrUpdate(根据会话可能会延迟FlushMode)和CreateSQLQuery(如果您使用的话,它总是立即执行)之间的会话ExecuteUpdate.

一般来说,如果你将NHibernate逻辑与低级SQL逻辑(存储过程等)结合起来,那么你将需要使用a 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();
}
Run Code Online (Sandbox Code Playgroud)

(FWIW - 严格来说,NHibernate事务在这里应该是不必要的,因为你之后没有对会话做任何事情Flush- 但是如果将来逻辑发生变化,最好使用显式NH事务.)

请注意,我更喜欢将IStatelessSession实例用于任何批量插入/更新/等.- 如果您正在使用常规ISession实例并且需要实际检索所做的更新ExecuteUpdate,那么您可能需要使用会话EvictClear方法来保证获取更新.