NHibernate会话(和无状态会话)和长时间运行的应用程序

时间:2012-10-10 10:17:37

标签: nhibernate .net-4.0 windows-services structuremap istatelesssession

在用于运行作业的Windows Web服务的上下文中,我们尝试重用我们为Web应用程序开发的NHibernate DAL。

对于会话管理,我们有两个选项,每个选项都有其优点和缺点:

有状态会话

  • 随着跟踪所有事情(L1 /会话缓存)而增长很多
  • 需要小心关闭,会话处理似乎不足以清除L1缓存(我注意到使用内存分析器)

无状态会话

  • 目前无法重用映射。声明为“lazy = true”的所有行李最终都会出现以下异常(即使会话尚未关闭):
  

初始化[...]未能懒惰地初始化角色集合:   [...],没有会议或会议结束

显然,我们无法使用lazy =“false”更新映射(它们与网络应用共享),这将是性能的一个巨大缺点

  • 无法与L2缓存交互:当部署共享L2缓存时,该服务将无法使L2缓存数据无效,以便Web应用程序获得最新的数据

到目前为止,NHibernate已被证明是好的,我们已成功在Web上下文中使用有状态会话和NHibernate LINQ,并使用了依赖注入的结构图。

我的问题是:

  • 在长时间运行的线程中使用NHibernate有什么好的解决方案吗?
  • 我更喜欢使用有状态会话,但如何避免内存泄漏?

2 个答案:

答案 0 :(得分:2)

问题解决了!实际上有几个问题。

第一个是关于实例的范围和多线程:

  • 为每个帖子创建一个新会话。
  • 一旦线程完成其工作,请清除连接到线程的所有实例。使用StructureMap,在线程中,使用new HybridLifecycle().FindCache().DisposeAndClear();。它将导致附加到线程的会话关闭并处置。
  • 当生命周期是线程范围时,StructureMap使用ThreadStatic变量来保持对对象缓存的引用。所以诀窍是在线程中调用StructureMap的ObjectFactory。最初,在我们的应用程序中,主线程负责创建新线程,并调用ObjectFactory。这是我们做的主要错误,并且一旦完成工作,确实无法清理线程。

会话类型:

  • 只要仔细处理实例化的StateFul会话,就不需要使用StateLessSession。在我们的例子中,StatelessSession有太多缺点(缓存管理是主要的)

重要说明:注意只需要实例化NHibernate NHibernate Session Factory一次!

当仔细管理NHibernate实例时,没有内存泄漏。

答案 1 :(得分:0)

在长时间运行的过程中保持有状态会话开放永远不是一个好主意。

我的建议是重新设计您的流程,将数据库相关代码与非数据库相关代码分开,这样任何与数据库相关的操作都可以保留在短跨度会话中。