问题描述:

We have our first NHibernate project going on pretty well. However, I still have not grasped the complete picture how to manage the sessions and objects in our scenario.

So, we are configuring a system structure in a persistent object model, stored in a database with NHibernate.

The system consists of physical devices, which the application is monitoring in a service process. So at service startup, we instantiate Device objects in the service and update their status according to data read from the device interface. The object model stays alive during the lifetime of the service.

The service is also serving Silverlight clients, which display object data and may also manipulate some objects. But they must access the same objects that the service is using for monitoring, for example, because the objects also have in-memory data as well, which is not persisted. (Yes, we are using DTO objects to actually transfer the data to the clients.)

Since the service is a multithreaded system, the question is how the NHibernate sessions should be managed.

I am now considering an approach that we would just have a background thread that would take care of object persistence in the background and the other threads would just place "SaveRequests" to our Repository, instead of directly accessing the NHibernate sessions. By this means, I can use a single session for the service and manage the NHibernate layer completely separate from the service and clients that access the objects.

I have not found any documentation for such a setup, since everyone is suggesting a session-per-request model or some variation. But if I get it right, if I instantiate an object in one session and save it in another one, it is not the same object - and it also seems that NHibernate will create a new entry in the database.

I've also tried to figure the role of IOC containers in this kond of context, but I have not found any useful examples that would show that they could really help me.

Am I on a right track or how should I proceed?

网友答案:

Consider ISession a unit of work. You will want to define within the context of your application, what constitutes a unit of work. A unit of work is a boundary around a series of smaller operations which constitute a complete, functional task (complete and functional is defined by you, in the design of your application). Is it when your service responds to a Silverlight client request, or other external request? Is it when the service wakes up to do some work on a timer? All of the above?

You want the session to be created for that unit of work, and disposed when it completes. It is not recommended that you use long-running ISession instances, where operations lazily use whatever ambient ISession they can find.

The idea is generally described as this:

  1. I need to do some work (because I'm responding to an event, whether it be an incoming request, a job on a timer, it doesn't matter).
  2. Therefore, I need to begin a new unit of work (which helps me keep track of all the operations I need to do while performing this work).
  3. The unit of work begins a new ISession to keep track of my work.
  4. I do my work.
  5. If I was able to do my job successfully, all my changes should be flushed and committed
    1. If not, roll all my changes back.
  6. Clean up after myself (dispose ISession, etc.).
相关阅读:
Top