【问题标题】:NHibernate caching and lazy loading providing unwanted resultsNHibernate 缓存和延迟加载提供了不需要的结果
【发布时间】:2013-06-14 14:10:09
【问题描述】:

我在使用 C# 和 ASP.NET 的 NHibernate 中遇到了一些主要的缓存和延迟加载问题。直到我们启用缓存才开始。在许多情况下,我们必须编写代码来清空对象并重新获取以保留所需的属性,否则会生成带有无效信息的文档或保存对象并覆盖最新数据。

其他时候,延迟加载无法获取数据并引发异常。在这些情况下,它始终是具有一对多关系的对象。所以我们有一个带有 IList 属性的对象,当我们遇到一个 foreach 循环时,它会抛出一个异常,指出它不能延迟加载集合。在这些情况下,我们只需对对象执行 getById 并实例化一个新对象。

下面是我使用的几个变通方法的伪代码。这些在大多数情况下都有效,但是,我不必编写这些额外的代码。

对于线程应用程序:

Thread thread = new Thread(new ThreadStart(() => GetObjectNotFromCache(objectGuid, out object)));
            thread.Start();
            thread.Join();

private static void  GetObjectNotFromCache(Guid objectId, out Object object)
    {
        var db = new db() // auto generated file that handles CRUD operations
        object= db.GetObjectById(objectId);
    }

对于网络应用:

var db = new db();
            object = db.GetObjectById(objectId);
            object = null;
            object = db.GetObjectById(objectId);

我们的会话管理器通过以下方式启用缓存:

 public static ISession OpenSession()
    {
        ISession session;
        if (CurrentSessionContext.HasBind(GetFactory()))
        {
            session = GetFactory().GetCurrentSession();
        }
        return session
    }

这些 hack 使我们能够继续开发,但是它们极大地减慢了我们的速度。谁能帮助确定这个问题可能发生在哪里?还有一点需要注意的是,在保存对象时,我们会驱逐当前会话。添加此功能是为了防止缓存在更新后持续存在。这确实有助于解决问题,但没有解决问题。

【问题讨论】:

    标签: c# asp.net nhibernate caching lazy-loading


    【解决方案1】:

    缓存对象的问题是它与当前会话断开连接。

    对于每个请求的网络会话模型,这将是一个问题。

    您需要将分离的缓存对象重新附加到当前会话:

    session.Lock(cachedObject, LockMode.None);
    

    但是,如果 cachedObject 在应用程序的其他地方是可写的,这会引发潜在的并发问题。我建议缓存用于只读数据,当您需要持久保存某些内容时,它几乎总是在您正在做的时候获取它的最佳方法。

    【讨论】:

    • 谢谢,这些知识帮助我理解为什么它正在做它正在做的事情,但是并不能有效地解决问题。也许最好的选择是不缓存并自行使用延迟加载。
    猜你喜欢
    • 2010-10-20
    • 1970-01-01
    • 2012-03-13
    • 2011-10-17
    • 1970-01-01
    • 2021-10-08
    • 2013-12-10
    • 2011-07-16
    • 2018-03-24
    相关资源
    最近更新 更多