Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate session management in Windows Service applications

Tags:

nhibernate

I'm developing and application that runs as a Windows service. There are other components which include a few WCF services, a client GUI and so on - but it is the Windows service that access the database.

So, the application is a long-running server, and I'd like to improve its performance and scalability, I was looking to improve data access among other things. I posted in another thread about second-level caching.

This post is about session management for the long-running thread that accesses the database. Should I be using a thread-static context? If so, is there any example of how that would be implemented.

Every one around the net who is using NHibernate seem to be heavily focussed on web-application style architectures. There seems to be a great lack of documentation / discussion for non-web app designs.

At the moment, my long running thread does this:

  1. Call 3 or 4 DAO methods
  2. Verify the state of the detached objects returned.
  3. Update the state if needed.
  4. Call a couple of DAO methods to persist the updated instances. (pass in the id of the object and the instance itself - the DAO will retrieve the object from the DB again, and set the updated values and session.SaveOrUpdate() before committing the transaction.
  5. Sleep for 'n' seconds
  6. Repeat all over again!

So, the following is a common pattern we use for each of the DAO methods:

  • Open session using sessionFactory.OpenSession()
  • Begin transaction
  • Do db work. retrieve / update etc
  • Commit trans
  • (Rollback in case of exceptions)
  • Finally always dispose transaction and session.Close()

This happens for every method call to a DAO class. I suspect this is some sort of an anti-pattern the way we are doing it.

However, I'm not able to find enough direction anywhere as to how we could improve it.

Pls note, while this thread is running in the background, doing its stuff, there are requests coming in from the WCF clients each of which could make 2-3 DAO calls themselves - sometimes querying/updating the same objects the long running thread deals with.

Any ideas / suggestions / pointers to improve our design will be greatly appreciated. If we can get some good discussion going, we could make this a community wiki, and possbily link to here from http://nhibernate.info

Krishna

like image 801
Krishna Avatar asked Oct 05 '08 08:10

Krishna


2 Answers

There seems to be a great lack of documentation / discussion for non-web app designs.

This has also been my experience. However, the model you are following seems correct to me. You should always open a session, commit changes, then close it again.

like image 93
steffenj Avatar answered Oct 21 '22 18:10

steffenj


This question is a little old now, but another technique would be to use Contextual Sessions rather than creating a new session in each DAO.

In our case, we're thinking of creating the session once per thread (for our multi-threaded win32 service), and make it available to the DAOs using either a property that returns SessionFactory.GetCurrentSession() (using the ThreadContext current session provider, so it's session-per-thread) or via DI (dependency injection - once again using ThreadContext.)

More info on GetCurrentSession and Contextual Sessions here.

like image 37
zcrar70 Avatar answered Oct 21 '22 20:10

zcrar70