NHibernate 会话的生命周期应该是多长?

发布于 2024-08-16 23:27:47 字数 298 浏览 5 评论 0原文

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

所以;处理会话的推荐方法是什么?他们的一生应该是怎样的?一次交易?一个单例会话可以处理所有事情?或者什么?

编辑:

请注意,我的应用程序架构是一个与服务器端服务通信的桌面应用程序,这是使用 NHibernate + Fluent 进行所有数据库处理的内容。 (如果这有什么区别的话......)

I'm new to NHibernate, and have seen some issues when closing sessions prematurely. I've solved this temporarily by reusing sessions instead of opening a session per transaction. However, I was under the impression that opening sessions each time you need them was the recommended approach for session lifetime management. No?

So; what is the recommended way of handling sessions? What should their lifetime be? One session pr transaction? One singleton session to handle everything? Or what?

Edit:

Note that my application architecture is a desktop application communicating with a server side service, which is what does all the Database handling, using NHibernate + Fluent. (If this makes any difference...)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤单情人 2024-08-23 23:27:47

您需要一个会话管理策略,使您的应用程序能够有效运行并利用 NHibernate 为您提供的功能 - 最显着的是缓存和延迟加载。

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

经验法则是:会话生存期需要足够长,以便会话结束后不会有持久对象在范围内徘徊。

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

在您的情况下,通过一个服务(我假设它作为 Windows 服务运行)执行 NHibernate 工作,您可能希望考虑为来自消费桌面应用程序的每个新请求创建一个会话,并处理当该请求得到满足时。不确切地知道您的服务如何运行以及桌面应用程序使用什么机制与之通信(远程处理?WCF?普通的旧式 SOAP?)我真的无法更具体。

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

如果您发现在这种策略下性能缓慢,则可能是您与数据库的对话过多并且您的对象图很复杂;在这种情况下,请查看二级缓存

You want a session management strategy that allows your app to function effectively and take advantage of the things that NHibernate gives you - most notably caching and lazy loading.

Creating sessions is an inexpensive process and requires little up-front RAM or CPU, so you shouldn't worry about conserving or re-using sessions (indeed, re-using them can lead to some nasty and un-anticipated side-effects). The session factory is the expensive thing and should be built once and only once at app startup.

The rule of thumb is this: the session lifetime needs to be long enough that you don't have persisted objects hanging around in scope after the session ends.

Once the session ends, all change tracking for objects you got from that session stops, so those changes don't get saved unless you deliberately re-attach that object to a new session. The session should therefore be around for as long as the objects you fetch from it are going to exist. In a Web app, that generally means a session for each request; in WinForms, a session for each form.

In your case, with a service (I assume it's running as a Windows service) doing the NHibernate work, you might wish to consider having a session created for each new request from the consuming desktop app, and disposing it when that request has been serviced. Not knowing exactly how your service runs and what mechanism the desktop app uses to talk to it (remoting? WCF? Plain old SOAP?) I can't really be more specific.

(There are some exceptions to this general rule - suppose you have a set of persisted objects that represent a shared resource to which other code will refer but not change, you can load these up-front at app-start and leave them disconnected from then on.)

If you find performance sluggish under such a strategy, it may be that you're just talking to the database too much and your object graph is complex; look at second-level caching in this case.

-残月青衣踏尘吟 2024-08-23 23:27:47

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

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

桌面的推荐做法
应用程序是使用每个会话
形式,以便每个形式
应用程序有自己的会话。每个
形式通常代表一种独特的
用户想要的作品
执行,所以匹配会话
生命周期的形式 生命周期的作品
实践中效果很好。所添加的
好处是你不再拥有
内存泄漏问题,因为
当您关闭其中的表单时
应用程序,您还可以处置
会议。这将使所有
加载的实体
有资格回收的会话
垃圾收集器 (GC)。

还有其他原因
更喜欢每个表单一个会话。
您可以利用 NHibernate 的
更改跟踪,因此它将刷新所有
当您对数据库进行更改时
提交交易。它还
在之间创建隔离屏障
不同的形式,所以你可以提交
对单个实体的更改无需
担心其他方面的改变
显示在其他实体上的实体
表格。

In a web app, you should have one session per request. This gives you full control over the session lifetime and simplifies error handling.

In a desktop app, I recommend using a session per presenter (or form if you prefer). To quote Ayende in his MSDN Magazine article:

The recommended practice for desktop
applications is to use a session per
form, so that each form in the
application has its own session. Each
form usually represents a distinct
piece of work that the user would like
to perform, so matching session
lifetime to the form lifetime works
quite well in practice. The added
benefit is that you no longer have a
problem with memory leaks, because
when you close a form in the
application, you also dispose of the
session. This would make all the
entities that were loaded by the
session eligible for reclamation by
the garbage collector (GC).

There are additional reasons for
preferring a single session per form.
You can take advantage of NHibernate’s
change tracking, so it will flush all
changes to the database when you
commit the transaction. It also
creates an isolation barrier between
the different forms, so you can commit
changes to a single entity without
worrying about changes to other
entities that are shown on other
forms.

夜血缘 2024-08-23 23:27:47

一个会话应该对应一个工作单元。当您使用该会话检索或保留的对象时,该会话应该保持活动状态。

A session should correspond to a unit of work. The session should stay alive while you are working with the objects retrieved or persisted using that session.

许久 2024-08-23 23:27:47

没有一种答案适合所有情况。 Nhibernate 之夏 的第 13 次会议对该问题进行了很好的概述。

There isn't one answer that fits all situations. Session 13 of Summer of Nhibernate presents a nice overview of the issue.

亣腦蒛氧 2024-08-23 23:27:47

NHibernate 框架和 Microsoft ADO.NET Entity Framework 的大部分内容都是相似的。这是一篇关于如何控制 ADO.NET EF 中的 ObjectContext 生命线的非常好的文章。

http://blogs.msdn.com/alexj/archive/2009/05/07/tip-18-how-to-decide-on-a-lifetime-for-your-objectcontext.aspx< /a>

它也应该适用于 NHibernate 会话。

Much of the NHibernate framework and Microsoft ADO.NET Entity Framework are similar. Here is a very good article about how you should control an ObjectContext lifeline in the ADO.NET EF.

http://blogs.msdn.com/alexj/archive/2009/05/07/tip-18-how-to-decide-on-a-lifetime-for-your-objectcontext.aspx

It should apply to NHibernate sessions as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文