2011-03-03 37 views
2

我们的应用最初是使用NHibernate构建的,其批处理的局限性也在考虑之中。然而,随着时间的推移,它已经转变为一个数据整理器,我们正在观察到一个重要的性能衰退。在会话中使用过多对象来提高NHibernate性能

会话最终不得不维护大约1000个或更多的对象,我们的分析表明,自动冲洗和脏检查是这里最大的违规者。我们尝试关闭自动刷新并在保存/更新操作中自行管理它,但这导致批处理保存/更新的灾难性性能。 我们正在寻找从会话中驱逐不需要的对象的选项。

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

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

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

回答

3

如果不知道更多关于您的需求,很难说,但也许您可以使用IStatelessSession。它没有第一级缓存担心。

Ayende对使用它的批量操作 here

+0

我们已经看过了使用无状态会话,但它不是一个可能的解决方案,因为它会需要一些架构的返工。感谢您的提示杰森。 我仍然在看''Session.Evict()'作为一个可能的生命保护程序,并想知道你是否有任何使用它的输入,如第二点所述。 – 2011-03-03 23:01:31

+1

我使用Session.Evict的唯一时间是当我知道我不需要对实体做任何事情并想释放一些内存(这对于批量操作很有用)。也许你可以使用ISession.GetSession创建一个子会话。它共享相同的连接,但保留自己的实体列表以进行刷新 – 2011-03-04 00:53:47

0

为什么不使用多个会话好的帖子,而不是一个大一个呢?这与关闭autoflush一起帮助我过去。另外,如果可能的话,您应该真的考虑使用HQL进行批量更新。

0

我知道这是旧的,但我只是在寻找其他东西时遇到了这个问题 - 刚刚解决了这个问题。我通过使用多个会话来解决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