NHibernate会话的生命周期应该是什么?

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

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

编辑:

请注意,我的应用程序体系结构是与服务器端服务进行通信的桌面应用程序,这是所有数据库使用NHibernate + Fluent处理的内容。 (如果这有什么区别…)

你需要一个会话pipe理策略,允许你的应用程序有效地工作,并利用NHibernate给你的东西 – 最显着的是caching和延迟加载。

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

经验法则是:会话生存期需要足够长,以便在会话结束后,没有持久化对象在范围内。

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

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

(这个通用规则有一些例外 – 假设你有一组代表一个共享资源的持久化对象,其他代码将引用但不会改变,你可以在app-start中预先加载这些对象,并保持它们与之断开上。)

如果在这种策略下你发现性能迟缓,那么你可能只是在和数据库交谈,而你的对象图很复杂; 看看这种情况下的二级caching 。

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

在桌面应用程序中,我build议每个演示者使用一个会话(或者如果您愿意的话)。 引用Ayende的MSDN杂志文章 :

桌面应用程序的推荐做法是使用每个表单的会话,以便应用程序中的每个表单都有自己的会话。 每个表单通常代表用户想要执行的一项独特的工作,因此将会话生命周期与表单生命周期进行匹配在实践中运行良好。 额外的好处是你不再有内存泄漏的问题,因为当你closures应用程序中的表单时,你也会处理会话。 这将使会话加载的所有实体都有资格被垃圾回收器(GC)回收。

还有其他原因希望每个表单只有一个会话。 您可以利用NHibernate的更改跟踪function,以便在提交事务时清除对数据库的所有更改。 它还在不同的表单之间创build了一个隔离屏障,因此您可以将更改提交到单个实体,而不用担心其他表单上显示的其他实体的更改。

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

没有一个适合所有情况的答案。 Nhibernate夏季第13节提出了一个很好的概述。

许多NHibernate框架和Microsoft ADO.NETentity 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会话。