4

In the context of a windows web service that's meant to run jobs, we try to reuse the NHibernate DAL we developed for the web application.

For session management we have two options, each one having its advantages and drawbacks:

Stateful session

  • Going to grow a lot as it keeps track of everything (L1/session cache)
  • Needs to be carefully closed, session disposal doesn't seem to be enough to clear L1 cache (what I noticed using memory profiler)

Stateless Session

  • Currently fails to reuse mappings. All bags declared with "lazy=true" ends up with the following exception (even though the session has not be closed):

Initializing [...] failed to lazily initialize a collection of role: [...], no session or session was closed

Obviously, we cannot update the mappings (they are shared with the web app) with lazy="false", it's gonna be a huge drawback for performances

  • Cannot interact with L2 cache: when shared L2 cache will be deployed, the service will be unable to invalidate L2 cache data in order for web application to have fresh up-to-date data

NHibernate has proven to be good until now, we have successfully used stateful session and NHibernate LINQ it in a web context, with structuremap for dependency injection.

My questions are:

  • Are there any good solutions to use NHibernate in a long running thread?
  • I'd prefer to use stateful session, but how to avoid memory leak?
Pierre Murasso
  • 591
  • 7
  • 14

2 Answers2

2

Problem solved! There were actually a couple of problems.

First one was about instances' scope, and multi-threading:

  • Create a new session for each thread.
  • As soon as the thread finishes its work, clean all the instances attached to the thread. With StructureMap, within the thread, use new HybridLifecycle().FindCache().DisposeAndClear();. It will cause the session attached to the thread to close and dispose.
  • When the lifecycle is thread scoped, StructureMap uses a ThreadStatic variable to keep a reference to the object cache. So the trick is to call StructureMap's ObjectFactory within the thread. Initially, in our application, a main thread was responsible for creating new threads, and call the ObjectFactory. That's the major mistake we did, and were indeed unable to clean the threads once their job was done.

Session type:

  • No need to use a StateLessSession, as soon as the StateFul sessions instantiated are carefully disposed. In our case, StatelessSession have too many drawbacks (cache management is the main)

Important remark: be careful to instantiate NHibernate NHibernate Session Factory only once!

When NHibernate instances are managed carefully, there is no memory leak.

Pierre Murasso
  • 591
  • 7
  • 14
0

It's never a good idea to keep a stateful session open in a long running process.

My suggestion is to redesign your process to separate database related code from non-database related code so any database related operation can be kept within a short-span session.

xing
  • 447
  • 2
  • 6