【问题标题】:Improving NHibernate performance with too many objects in session在会话中使用太多对象来提高 NHibernate 性能
【发布时间】:2011-03-03 01:36:27
【问题描述】:

我们的应用最初是使用 NHibernate 构建的,并且考虑到了批处理的局限性。然而,随着时间的推移,它已经转变为数据处理器,我们观察到性能显着下降。

会话最终不得不维护大约 1000 个或更多对象,我们的分析显示,自动刷新和脏检查是这里最大的问题。我们尝试关闭自动刷新并在保存/更新操作中自行管理它,但这会导致批量保存/更新的灾难性性能。 我们现在正在考虑从会话中逐出不需要的对象的选项。

  1. 我遇到了二级缓存驱逐方法 (sessionFactory.Evict(typeof(Cat));),它允许我们按类型驱逐,但我们不使用二级缓存。我仍然可以使用此方法从一级缓存中逐出对象吗?
  2. 我还读到了一种获取对象的模式,将它们从会话中逐出,然后在需要时通过调用它们的 Update() 将它们与会话重新关联。这是一个推荐和接受的模式,因为我还读到 NH3 已经为此设置了一堵墙? (我们还没有升级到NH3,我们仍然可以使用它)

虽然我们意识到我们没有以最佳方式使用 NHibernate,但我们只是希望以某种方式改善当前情况。非常感谢您对上述问题的回答和任何其他建议/建议。谢谢。

更新
在查看了 NH 文档和代码后,我意识到 1 可能是不可能的。我仍在寻找有关使用 Evict() 的一些指示或技巧。我能够大幅减少会话中的对象数量。但是仍然不知道在更新或删除被驱逐的对象时是否需要付出代价。提前感谢您的帮助。

【问题讨论】:

    标签: performance nhibernate


    【解决方案1】:

    如果不了解您的要求,很难说,但也许您可以使用 IStatelessSession。它不需要担心一级缓存。

    Ayende 有一篇关于将其用于批量操作的好帖子 here

    【讨论】:

    • 我们已经研究过使用无状态会话,但它不是立即可行的解决方案,因为它需要对架构进行一些返工。感谢您的提示杰森。我仍然将Session.Evict() 视为可能的救生员,并想知道您是否对使用它有任何意见,如第二点所述。
    • 我使用 Session.Evict 的唯一时间是当我知道我不需要对实体执行任何其他操作并想要释放一些内存时(这对于批量操作很有用)。也许您可以使用 ISession.GetSession 来创建子会话。它共享相同的连接,但保留自己的要刷新的实体列表
    【解决方案2】:

    为什么不使用更多的会话,而不是一个大会话?这与关闭自动刷新一起在过去帮助了我。此外,如果可能,您应该真正考虑使用 HQL 进行批量更新。

    【讨论】:

      【解决方案3】:

      我知道这是旧的,但我只是在寻找其他东西时遇到了这个——刚刚解决了这个问题。我确实通过使用多个会话解决了 Trent 提到的问题。我会创建一个会话来获取我想要的所有对象,然后关闭该会话。我的情况是遍历列表并对每个对象进行操作并尝试在每次迭代中提交。然后,我将在我的列表上创建 foreach,在循环内创建和处理一个新会话,将我的对象从列表重新附加到新会话。这需要花费大约 2.5 小时到 2 分 40 秒的过程!

      有关我如何解决它的灵感,请参阅这篇文章——尽管与我在 NHibernate 周围的工作单元包装器不完全一样:

      http://weblogs.asp.net/ricardoperes/archive/2013/03/21/attaching-disconnected-entities-in-nhibernate-without-going-to-the-database.aspx

      【讨论】:

        猜你喜欢
        • 2016-12-11
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        • 2023-04-01
        • 2021-05-19
        • 2011-11-05
        • 2014-04-08
        • 1970-01-01
        相关资源
        最近更新 更多