NHibernate缓存和延迟加载提供不需要的结果

时间:2013-06-14 14:10:09

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

我一直在使用C#和ASP.NET体验NHibernate的一些主要缓存和延迟加载问题。直到我们启用缓存才开始这样做。在许多情况下,我们必须编写代码以使对象无效并使用新的get来保留所需的属性,否则将生成包含无效信息的文档或保存对象并覆盖最新数据。

其他时候,延迟加载无法获取数据并引发异常。在这些情况下,它始终是具有一对多关系的对象。所以我们有一个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
    }

这些黑客攻击让我们继续发展,但是,它们让我们的速度大大降低。任何人都可以帮助确定这个问题可能发生在哪里?还有一点需要注意的是,在保存对象时,我们会驱逐当前会话。添加此项是为了防止缓存在更新后保持不变。这确实有助于解决问题,但没有解决问题。

1 个答案:

答案 0 :(得分:1)

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

使用每个请求的Web会话模型,这将成为一个问题。

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

session.Lock(cachedObject, LockMode.None);

但如果cachedObject在应用程序的其他位置可写,则会引发潜在的并发问题。我建议缓存是用于只读数据,当你需要保留某些东西时,它几乎总是最好的方法来获取新的东西。