Windows服务应用程序中的NHibernate会话管理
我正在开发一个作为Windows服务运行的应用程序。还有其他一些组件,包括一些WCF服务、客户端GUI等等,但访问数据库的是Windows服务 因此,这个应用程序是一个长期运行的服务器,我想提高它的性能和可伸缩性,我希望在其他方面改进数据访问。我在另一个帖子中发布了关于二级缓存的内容 这篇文章是关于访问数据库的长时间运行线程的会话管理。 我应该使用线程静态上下文吗? 如果是的话,有没有关于如何实施的例子 网络上每一个使用NHibernate的人似乎都非常关注web应用程序风格的架构。对于非web应用程序设计,似乎非常缺乏文档/讨论 目前,我的长时间运行线程执行以下操作:Windows服务应用程序中的NHibernate会话管理,nhibernate,Nhibernate,我正在开发一个作为Windows服务运行的应用程序。还有其他一些组件,包括一些WCF服务、客户端GUI等等,但访问数据库的是Windows服务 因此,这个应用程序是一个长期运行的服务器,我想提高它的性能和可伸缩性,我希望在其他方面改进数据访问。我在另一个帖子中发布了关于二级缓存的内容 这篇文章是关于访问数据库的长时间运行线程的会话管理。 我应该使用线程静态上下文吗? 如果是的话,有没有关于如何实施的例子 网络上每一个使用NHibernate的人似乎都非常关注web应用程序风格的架构。对于非web
- 使用sessionFactory.OpenSession()打开会话
- 开始交易
- 执行数据库工作。检索/更新等
- 提交trans
- (异常情况下的回滚)
- 最后,始终处置事务和会话。Close()
这也是我的经验。但是,您所遵循的模式在我看来似乎是正确的。您应该始终打开一个会话,提交更改,然后再次关闭它。我同意,有状态应用的示例并不多。 我正在考虑做以下工作: 和你一样,我也有一个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();
}
}