2010-01-06 74 views
41

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

所以;处理会话的推荐方式是什么?他们的一生应该是什么?一个会话pr交易?一个单独的会话来处理一切?或者是什么?

编辑:

请注意,我的应用程序体系结构是一个桌面应用程序与服务器端的服务,这是什么做所有的数据库处理,使用NHibernate +流利的沟通。 (如果这有什么区别...)

+2

在你的问题http://stackoverflow.com/questions/2011950/nhibernate-mappings-issue-when-referencing-class-lazy-load-issue你问我看看这个新的问题,但我看到你'已经得到了充分的报道。我在这里提出了一些意见,但请注意,会议和交易似乎混杂在讨论中,而这些意见是不同的。此外,会话池或超时触发的会话在性能方面可能是有益的,但是很难安装和正确使用。还要注意,无论您选择哪种模式,都会使用连接池。 – Abel 2010-01-06 23:42:46

+0

感谢您的评论亚伯。在我看到的例子中,会话和事务经常共享相同的生命周期,但正如在引用的问题中看到的那样,这可能有时候会成为问题。我希望人们已经回答了“会话生命周期” - 而不是“事务生命周期”这是这种情况的印象。 – stiank81 2010-01-07 06:47:17

回答

26

你想要一个会话管理策略,允许你的应用程序有效地运行并利用NHibernate给你的东西 - 最显着的是缓存和延迟加载。

创建会话是一个廉价的过程,需要很少的前期RAM或CPU,所以你不应该担心保存或重用会话(实际上,重新使用它们可能会导致一些令人讨厌和不可预料的一面效果 - )。会话工厂是非常昂贵的事情,应该在应用程序启动时一次性构建一次。

经验法则是:会话生存需要足够长,你没有持久对象徘徊范围在会话结束后。

一旦会话结束,所有的变化对于您从会议得到了目标跟踪停止,所以这些变化没有得到保存,除非你刻意该对象重新连接到一个新的会话。因此,只要您从中获取的对象将存在,该会话就应该存在。在Web应用程序中,通常表示每个请求的会话;在WinForms中,每个表单都有一个会话。您可能希望考虑为使用消费桌面应用程序的每个新请求创建一个会话,然后将其置于一个服务器上(我假设它运行的是作为Windows服务的)当该请求已被服务时。不知道你的服务是如何运行的,以及桌面应用程序使用什么机制来与它交谈(远程处理?WCF?普通的旧SOAP?)我不能更具体。

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

如果你发现在这样的战略表现低迷,这可能是因为你只是谈话的数据库太多,你的对象图是复杂的;在这种情况下请看second-level caching

+0

谢谢!关于我的服务,我正在使用WCF,目前使用soap作为控制台应用程序运行,但我认为这不会产生任何影响,所以您足够具体。听起来合理的是每个请求都有一个会话。目前,我只使用正在运行事务的会话,并且似乎有一些引用的数据在事务处理期间未加载,因为会话已关闭而失败。 – stiank81 2010-01-06 19:29:30

6

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

0

许多NHibernate框架和Microsoft ADO.NET Entity Framework都很相似。这里有一篇关于如何控制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的会议以及。

+1

在我看来,由于EF 1.0/3.5不支持基于自动代理的延迟加载,EF和NHibernate在这个问题上的差异太大,无法有效地分享建议。 EF中的ObjectContext生命周期更易于管理,因为EF不像功能丰富。 – 2010-01-06 15:39:22

+0

你是正确的,EF 1.0不支持,但EF 2.0。这篇文章似乎适用于两者。 – 2010-01-06 16:36:02

11

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

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

建议的做法桌面 应用程序是每 形式使用会话,这样在 申请每种形式都有它自己的会话。每个 表单通常表示用户希望 执行的不同的 工作,因此在实践中将会话 生命期匹配到表单生存期的工作很好地工作 。增加的 好处是您不再有 内存泄漏问题,因为 当您关闭 应用程序中的表单时,您也会处理 会话。这将使 会话加载的所有 实体有资格被垃圾收集器(GC)的 回收。

还有其他原因希望每个表单只有一个会话。 您可以利用NHibernate的 更改跟踪功能,因此当您提交事务时,它将刷新数据库的所有 更改。它还 创建 不同形式之间的隔离屏障,所以你可以提交 更改为单一实体,而不 担心被显示在其他 形式的变化等 实体。

+0

“每次操作的会话”相当模糊。你应该提到“每个请求的会话” – 2010-01-06 14:27:06

相关问题