Windows服务应用程序中的NHibernate会话管理

Windows服务应用程序中的NHibernate会话管理,nhibernate,Nhibernate,我正在开发一个作为Windows服务运行的应用程序。还有其他一些组件,包括一些WCF服务、客户端GUI等等,但访问数据库的是Windows服务 因此,这个应用程序是一个长期运行的服务器,我想提高它的性能和可伸缩性,我希望在其他方面改进数据访问。我在另一个帖子中发布了关于二级缓存的内容 这篇文章是关于访问数据库的长时间运行线程的会话管理。 我应该使用线程静态上下文吗? 如果是的话,有没有关于如何实施的例子 网络上每一个使用NHibernate的人似乎都非常关注web应用程序风格的架构。对于非web

我正在开发一个作为Windows服务运行的应用程序。还有其他一些组件,包括一些WCF服务、客户端GUI等等,但访问数据库的是Windows服务

因此,这个应用程序是一个长期运行的服务器,我想提高它的性能和可伸缩性,我希望在其他方面改进数据访问。我在另一个帖子中发布了关于二级缓存的内容

这篇文章是关于访问数据库的长时间运行线程的会话管理。 我应该使用线程静态上下文吗? 如果是的话,有没有关于如何实施的例子

网络上每一个使用NHibernate的人似乎都非常关注web应用程序风格的架构。对于非web应用程序设计,似乎非常缺乏文档/讨论

目前,我的长时间运行线程执行以下操作:

  • 调用3或4个DAO方法
  • 验证返回的分离对象的状态
  • 如果需要,更新状态
  • 调用两个DAO方法来持久化更新的实例。(传入对象id和实例本身-DAO将再次从DB中检索对象,并在提交事务之前设置更新的值和session.SaveOrUpdate()
  • 睡眠“n”秒
  • 再重复一遍
  • 因此,以下是我们用于每个DAO方法的常见模式:

    • 使用sessionFactory.OpenSession()打开会话
    • 开始交易
    • 执行数据库工作。检索/更新等
    • 提交trans
    • (异常情况下的回滚)
    • 最后,始终处置事务和会话。Close()
    对DAO类的每个方法调用都会发生这种情况。 我怀疑这是一种反模式的方式,我们这样做

    然而,我无法在任何地方找到足够的方向来改进它

    请注意,当这个线程在后台运行时,会有来自WCF客户机的请求,每个请求都可能自己进行2-3次DAO调用——有时查询/更新长时间运行的线程处理的相同对象

    如有任何改进我们设计的想法/建议/建议,我们将不胜感激。 如果我们能进行一些很好的讨论,我们可以把它变成一个社区维基,并可能从这里链接到这里

    克里希纳

    对于非web应用程序设计,似乎非常缺乏文档/讨论


    这也是我的经验。但是,您所遵循的模式在我看来似乎是正确的。您应该始终打开一个会话,提交更改,然后再次关闭它。

    我同意,有状态应用的示例并不多。 我正在考虑做以下工作:

    和你一样,我也有一个windows服务,它承载了许多WCF服务。所以WCF服务是入口点。 最终,我所有的WCF服务都继承自AbstractService,它处理大量日志记录和基本的数据库插入/更新

    在我见过的最好的NHibernate帖子之一中,HttpModule执行以下操作: 看


    因此,也许我应该在AbstractService中做一些类似的事情。因此,有效地,我将以每次服务调用的会话结束。如果您查看上面的NHib最佳实践文章链接,您将看到,只要我打开和关闭会话,NHibernateSessionManager就应该处理所有其他事情(抽象服务构造函数和析构函数)


    只是一个想法。但我遇到了错误,因为我的会话似乎挂起时间太长,并且我得到了臭名昭著的错误-NHibernate.AssertionFailure:entry中的null id(在异常发生后不要刷新会话).

    您也可以在不关闭会话的情况下刷新会话,它实现了同样的效果。我做到了。

    这个问题现在有点老了,但另一种技术是使用上下文会话,而不是在每个DAO中创建新会话

    在我们的例子中,我们考虑每个线程创建一次会话(对于我们的多线程win32服务),并使用返回SessionFactory.GetCurrentSession()的属性(使用ThreadContext当前会话提供程序,即每个线程的会话)或通过DI将其提供给DAO(依赖项注入-再次使用ThreadContext。)


    .

    我们最近开始使用IoC容器来管理会话生命周期,作为上述上下文会话的替代。(更多详细信息)。

    +1.我多次看到这个一般性建议:SessionFactory很昂贵。只创建一次。会话很便宜。
    private void BeginTransaction(object sender, EventArgs e) {
        NHibernateSessionManager.Instance.BeginTransaction();
    }
    private void CommitAndCloseSession(object sender, EventArgs e) {
        try {
            NHibernateSessionManager.Instance.CommitTransaction();
        }
        finally {
            NHibernateSessionManager.Instance.CloseSession();
        }
    }