NHibernate FlushMode 在查找前自动不刷新

标签 nhibernate

好吧,我看到一些帖子问几乎相同的事情,但要点有点不同。

这是一个经典案例:我正在保存/更新一个实体,并且在 中相同的 session ,我正在尝试使用 FlushMode = Auto 从数据库中获取它们(使用标准/查找/枚举/等)。事情是: NHibernate 在查询之前不会刷新更新 ,所以我从数据库中得到不一致的数据。

“足够公平”,有些人会说,正如文档所述:

This process, flush, occurs by default at the following points:

  • from some invocations of Find() or Enumerable()
  • from NHibernate.ITransaction.Commit()
  • from ISession.Flush()


大胆的“一些调用”清楚地表明NH完全没有责任。但是,IMO 在这里存在一致性问题,因为文档还指出:

Except when you explicity Flush(), there are absolutely no guarantees about when the Session executes the ADO.NET calls, only the order in which they are executed. However, NHibernate does guarantee that the ISession.Find(..) methods will never return stale data; nor will they return the wrong data.



因此,如果我使用 CreateQuery(查找替换)并过滤属性值为 20 的实体,则 NH 可能 不是 返回 Value = 30 的实体,对吗?但这就是实际发生的事情,因为 Flush 不会在它应该自动发生的时候自动发生。
public void FlushModeAutoTest()
{
    ISession session = _sessionFactory.OpenSession();
    session.FlushMode = FlushMode.Auto;

    MappedEntity entity = new MappedEntity() { Name = "Entity", Value = 20 };
    session.Save(entity);

    entity.Value = 30;
    session.SaveOrUpdate(entity);

    // RETURNS ONE ENTITY, WHEN SHOULD RETURN ZERO
    var list = session.CreateQuery("from MappedEntity where Value = 20").List<MappedEntity>();

    session.Flush();
    session.Close();
}

毕竟:我是不是弄错了,它是一个错误还是仅仅是一个不可预测的功能,所以每个人都必须调用 Flush 来确保它的工作?

谢谢你。

飞利浦

最佳答案

我对 NHibernate 源代码不是很熟悉,但是 2.1.2.GA 版本中 ISession 实现的这个方法可能会回答这个问题:

/// <summary>
/// detect in-memory changes, determine if the changes are to tables
/// named in the query and, if so, complete execution the flush
/// </summary>
/// <param name="querySpaces"></param>
/// <returns></returns>
private bool AutoFlushIfRequired(ISet<string> querySpaces)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        CheckAndUpdateSessionStatus();
        if (!TransactionInProgress)
        {
            // do not auto-flush while outside a transaction
            return false;
        }
        AutoFlushEvent autoFlushEvent = new AutoFlushEvent(querySpaces, this);
        IAutoFlushEventListener[] autoFlushEventListener = listeners.AutoFlushEventListeners;
        for (int i = 0; i < autoFlushEventListener.Length; i++)
        {
            autoFlushEventListener[i].OnAutoFlush(autoFlushEvent);
        }
        return autoFlushEvent.FlushRequired;
    }
}

我认为这意味着自动刷新只会保证事务内部的一致性,这是有道理的。尝试使用事务重写您的测试,我很好奇这是否能解决问题。

关于NHibernate FlushMode 在查找前自动不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3295169/

相关文章:

nhibernate - 为什么从 Session 中逐出对象不会提交对数据库的更改?

c# - 适当的 Guid 映射。 hibernate

nhibernate - 如何在 FluentNHibernate 中创建复合 UNIQUE 约束?

c# - 在存储库线程中锁定单个 session 是否安全? (N休眠)

c# - 我如何告诉 NHibernate 只保存更改的属性

c# - NHibernate 自定义连接字符串配置

nhibernate - 如何使用 NHibernate 插入或更新(或覆盖)记录?

nhibernate - 为什么 ROW_NUMBER OVER(ORDER BY 列)返回的结果顺序与仅 ORDER BY 列不同?

nhibernate - SQL Server CE 是否支持使用 NHibernate 更新架构?

nhibernate - 这是将 NHibernate Isession 作为 PerWebRequest 处理的好解决方案吗