NHibernate FlushMode查找前自动不刷新 [英] NHibernate FlushMode Auto Not Flushing Before Find

查看:130
本文介绍了NHibernate FlushMode查找前自动不刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我已经看到一些帖子询问几乎相同的内容,但要点有所不同.

All right, I've seen some posts asking almost the same thing but the points were a little bit different.

这是一个典型的案例:我正在保存/更新实体,并且在 SAME SESSION 中,我试图从数据库中获取它们(使用条件/查找/枚举/等),且FlushMode = Auto.问题是: NHibernate在查询之前不会刷新更新,所以我从数据库中获取不一致的数据.

This is a classic case: I'm saving/updating an entity and, within the SAME SESSION, I'm trying to get them from the database (using criteria/find/enumerable/etc) with FlushMode = Auto. The matter is: NHibernate isn't flushing the updates before querying, so I'm getting inconsistent data from the database.

足够好",如文档所述:

"Fair enough", some people will say, as the documentation states:

默认情况下,在以下几点发生此刷新过程:

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

  • 来自Find()或Enumerable()的一些调用
  • 来自NHibernate.ITransaction.Commit()
  • 来自ISession.Flush()
  • from some invocations of Find() or Enumerable()
  • from NHibernate.ITransaction.Commit()
  • from ISession.Flush()

大胆的某些引用"清楚地表明NH完全不承担任何责任. IMO,但是,我们在这里存在一个一致性问题,因为该文档还指出:

The bold "some invocations" clearly says that NH has no responsibility at all. IMO, though, we have a consistency problem here because the doc also states that:

除非显式地使用Flush(),否则绝对不能保证Session在何时执行ADO.NET调用,仅保证它们执行的顺序.但是, NHibernate确实保证了ISession.Find(..)方法将永远不会返回过时的数据.他们也不会返回错误的数据.

因此,如果我使用CreateQuery(查找替换)并筛选属性值为Value = 20的实体,则NH可能返回值为Value = 30的实体,对吗?但是实际上就是这样,因为刷新不会在应有的时候自动发生.

So, if I'm using CreateQuery (Find replacement) and filtering for entities with property Value = 20, NH may NOT return entities with Value = 30, right? But that's what happens in fact, because the Flush is not happening automatically when it should.

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来确保其工作正常?

After all: am I getting it wrong, is it a bug or simply a non predictable feature so everybody have to call Flush to assure its work?

谢谢.

Filipe

推荐答案

我不太熟悉NHibernate源代码,但是2.1.2.GA版本中ISession实现中的此方法可能会回答以下问题:

I'm not very familiar with the NHibernate source code but this method from the ISession implementation in the 2.1.2.GA release may answer the question:

/// <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;
    }
}

我的意思是,自动刷新将仅保证事务内部的一致性,这是有道理的.尝试使用事务重写您的测试,我很好奇这是否可以解决问题.

I take this to mean that auto flush will only guarantee consistency inside a transaction, which makes some sense. Try rewriting your test using a transaction, I'm very curious if that will fix the problem.

这篇关于NHibernate FlushMode查找前自动不刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆