【问题标题】:NHibernate session (and stateless session) and long running applicationNHibernate 会话(和无状态会话)和长时间运行的应用程序
【发布时间】:2012-10-10 10:17:36
【问题描述】:

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

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

有状态会话

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

无状态会话

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

Initializing [...] 未能延迟初始化角色集合: [...],没有会话或会话已关闭

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

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

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

我的问题是:

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    会话类型:

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

    重要提示:注意NHibernate NHibernate Session Factory 只实例化一次!

    仔细管理 NHibernate 实例时,不会出现内存泄漏。

    【讨论】:

      【解决方案2】:

      在长时间运行的进程中保持有状态会话打开绝不是一个好主意。

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

      【讨论】:

        猜你喜欢
        • 2011-03-22
        • 1970-01-01
        • 2017-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-07
        • 1970-01-01
        • 2013-11-06
        相关资源
        最近更新 更多