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

sti*_*k81 41 .net nhibernate session lifetime

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

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

编辑:

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

Nei*_*itt 26

您需要一个会话管理策略,允许您的应用程序有效运行并利用NHibernate为您提供的功能 - 最值得注意的是缓存和延迟加载.

创建会话是一个廉价的过程,需要很少的前期RAM或CPU,因此您不必担心保存或重新使用会话(实际上,重新使用它们会导致一些令人讨厌和无法预料的副作用).会话工厂是昂贵的东西,应该只在应用程序启动时建立一次.

经验法则是:会话生命周期需要足够长,以至于在会话结束后您没有持久化对象在范围内.

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

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

(这个一般规则有一些例外 - 假设你有一组持久化对象代表共享资源,其他代码将引用但不会更改,你可以在应用程序启动时预先加载它们并让它们从那时断开连接上.)

如果你发现在这样的策略下性能低迷,那么你可能只是过多地与数据库交谈并且你的对象图很复杂; 看看这种情况下的二级缓存.


R. *_*des 11

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

在桌面应用程序中,我建议每个演示者使用一个会话(如果您愿意,可以使用表单).在他的MSDN杂志文章中引用Ayende :

桌面应用程序的推荐做法是对每个表单使用一个会话,以便应用程序中的每个表单都有自己的会话.每个表单通常代表用户想要执行的独特工作,因此将会话生命周期与表单生命周期相匹配在实践中非常有效.额外的好处是您不再遇到内存泄漏问题,因为当您关闭应用程序中的表单时,您也会处置该会话.这将使会话加载的所有实体都有资格通过垃圾收集器(GC)进行回收.

每个表单更喜欢单个会话还有其他原因.您可以利用NHibernate的更改跟踪,因此在提交事务时它将刷新对数据库的所有更改.它还在不同的表单之间创建隔离屏障,因此您可以将更改提交到单个实体,而无需担心对其他表单上显示的其他实体的更改.


Dav*_*d M 6

会话应对应于工作单元.在使用该会话检索或持久保存的对象时,会话应保持活动状态.