1

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

4

1 回答 1

1

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

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

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

session.Lock(cachedObject, LockMode.None);

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

于 2013-06-14T14:45:59.830 回答