gpt4 book ai didi

NHibernate FlushMode 在查找前自动不刷新

转载 作者:行者123 更新时间:2023-12-03 12:22:18 25 4
gpt4 key购买 nike

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

这是一个经典案例:我正在保存/更新一个实体,并且在 中相同的 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com