【问题标题】:What should be the lifetime of an NHibernate session?NHibernate 会话的生命周期应该是多少?
【发布时间】:2011-01-02 01:51:30
【问题描述】:

我是 NHibernate 的新手,在过早关闭会话时遇到了一些问题。我通过重用会话而不是为每个事务打开一个会话来暂时解决了这个问题。但是,我的印象是,每次需要时打开会话是会话生命周期管理的推荐方法。不?

所以;处理会话的推荐方式是什么?他们的一生应该是怎样的?一个会话 pr 交易?一个单例会话来处理所有事情?要不然是啥?

编辑:

请注意,我的应用程序架构是与服务器端服务通信的桌面应用程序,这是使用 NHibernate + Fluent 处理所有数据库的内容。 (如果这有什么不同...)

【问题讨论】:

  • 在您的问题stackoverflow.com/questions/2011950/… 中,您要求我调查这个新问题,但我看到您已经收到了充分的报道。我支持这里的一些观点,但请注意,似乎会话和事务在讨论中混杂在一起,而它们是不同的东西。此外,会话池或超时触发的会话在性能方面可能是有益的,但设置和正确设置却很棘手。另请注意,无论您选择何种模式,都会在底层使用连接池。
  • 感谢您的评论亚伯。在示例中,我看到会话和事务通常共享相同的生命周期,但正如在引用的问题中看到的那样,这有时可能是一个问题。我希望人们已经回答了“会话生命周期” - 而不是“事务生命周期”,我在印象就是这样。

标签: .net nhibernate session lifetime


【解决方案1】:

您需要一种会话管理策略,使您的应用程序能够有效运行并利用 NHibernate 为您提供的功能 - 尤其是缓存和延迟加载。

创建会话是一个成本低廉的过程,并且需要很少的前期 RAM 或 CPU,因此您不必担心保存或重复使用会话(实际上,重复使用它们可能会导致一些令人讨厌和意想不到的副作用 -影响)。会话工厂是昂贵的东西,应该在应用启动时构建一次且仅一次。

经验法则是这样的:会话生命周期需要足够长,以至于会话结束后不会有持久对象在范围内徘徊。

会话结束后,您从该会话获得的对象的所有更改跟踪都会停止,因此除非您故意将该对象重新附加到新会话,否则这些更改不会被保存。因此,只要您从中获取的对象存在,该会话就应该存在。在 Web 应用程序中,这通常意味着每个请求都有一个会话;在 WinForms 中,每个表单都有一个会话。

在您的情况下,使用一个服务(我假设它运行 作为 Windows 服务)执行 NHibernate 工作,您可能希望考虑为来自消费桌面应用程序的每个新请求创建一个会话, 并在该请求得到服务时处理它。不知道您的服务是如何运行的,以及桌面应用程序使用什么机制与之交谈(远程处理?WCF?普通的旧 SOAP?)我真的不能更具体。

(此一般规则有一些例外情况 - 假设您有一组持久对象,它们表示其他代码将引用但不会更改的共享资源,您可以在应用程序启动时预先加载这些并保留它们从此断开连接。)

如果您发现在这种策略下性能变慢,可能是您与数据库的对话过多,而您的对象图很复杂;在这种情况下查看second-level caching

【讨论】:

  • 谢谢!关于我的服务,我正在使用 WCF,目前使用的是 soap - 作为控制台应用程序运行,但我认为这不会有任何区别,所以你足够具体。为每个请求设置一个会话听起来很合理。目前我只使用正在运行事务的会话,并且似乎有一些在事务期间未加载的引用数据由于会话关闭而失败。
【解决方案2】:

在网络应用程序中,每个请求应该有一个会话。这使您可以完全控制会话生命周期并简化错误处理。

在桌面应用程序中,我建议为每个演示者使用一个会话(或者,如果您愿意,也可以使用表单)。引用 Ayende 在他的 MSDN Magazine article 中的话:

桌面的推荐做法 应用程序是使用每个会话 形式,使每个形式在 应用程序有自己的会话。每个 形式通常代表不同的 用户想要的工作 执行,所以匹配会话 生命周期的形式生命周期的作品 在实践中相当好。添加的 好处是你不再拥有 内存泄漏问题,因为 当您在 应用程序,您还处置 会议。这将使所有 加载的实体 符合回收条件的会话 垃圾收集器 (GC)。

还有其他原因 更喜欢每个表单一个会话。 您可以利用 NHibernate 的 更改跟踪,因此它将刷新所有 当您更改数据库时 提交事务。它也是 创建之间的隔离屏障 不同的形式,所以你可以提交 更改为单个实体而无需 担心别人的变化 显示在其他实体上的实体 表格。

【讨论】:

  • “每个操作的会话”相当模糊。您应该提及“每个请求的会话”
【解决方案3】:

一个会话应该对应一个工作单元。当您处理使用该会话检索或保留的对象时,该会话应该保持活动状态。

【讨论】:

    【解决方案4】:

    没有适合所有情况的答案。 Summer of Nhibernate 的第 13 场会议很好地概述了这个问题。

    【讨论】:

      【解决方案5】:

      NHibernate 框架和 Microsoft ADO.NET 实体框架的大部分内容是相似的。这是一篇关于如何在 ADO.NET EF 中控制 ObjectContext 生命线的非常好的文章。

      http://blogs.msdn.com/alexj/archive/2009/05/07/tip-18-how-to-decide-on-a-lifetime-for-your-objectcontext.aspx

      它也应该适用于 NHibernate 会话。

      【讨论】:

      • 在我看来,由于 EF 1.0/3.5 不支持基于自动代理的延迟加载,因此 EF 和 NHibernate 在这个问题上的差异太大,无法有效地分享建议。 EF 中的 ObjectContext 生命周期更易于管理,因为 EF 功能并不丰富。
      • 你是正确的,EF 1.0 不支持,但 EF 2.0 支持。这篇文章似乎适用于两者。
      猜你喜欢
      • 1970-01-01
      • 2010-09-14
      • 2016-04-12
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2011-08-21
      • 2016-11-21
      相关资源
      最近更新 更多