NHibernate/NHProf Dependency Injection and Sessions

Hi,

I recently been working with the Castle.Components.Scheduler and Jobs. The job runs in a NServiceBus host on Version:  2.0.0.1219

Basically, I created a Job that implemented IJob and had constructor injection for the NHibernate Session.

<!–Castle.Components.Scheduler–>
<component id=”TheJob”
service=”Castle.Components.Scheduler.IJob”
type=”Romiko.TheJob, Romiko”
lifestyle=”transient”/>

  public class TheJob : TheJobBase, IJob
    {
        public TheJob(Idependency1 dep1, Idependency2 dep2, ISession myNHSession)
            : base(dep1, dep2,myNHSession) )
        {
        }

        public override bool Execute(JobExecutionContext context)
        {
            Process(context);
            return true;
        }

I colleague of mine, Matthew Wills, from Readify has been telling me how much NHProf can save you time, and indeed today it was proved Smile

The process method above runs a series of job steps which execute 3 SQL select staments.

NHProf was moaning about the Session being shared:

Alert: Using a single session in multiple threads is likely a bug

Alert: Use of implicit transactions is discouraged

 

We noticed that subsequent job runs were using the same session!

image

See above, that 1 session is being used by the job, which runs all the time, this is not good at all for performance. The above shows the job running 4 to 5 times, each time executing 3 statements.

So, what we did, was remove the Session from the constructor injection, as we found a bug where a session was being created on one thread (in constructor) and then used in another thread (in the execute method).

To solve the problem above, we used Windsor to resolve the dependency in the execute method instead.

 public override bool Execute(JobExecutionContext context)
        {
            _session = WindsorAccessor.Container.Resolve<ISession>();
            Process(context);
            return true;
        }

Now, when we run NHProf, we get a sessoin per job and no longer hold a session for along time on a long running process within NServiceBus.

Lets rerun the code now and see how it works when we run 4 to 5 jobs Smile

image

 

From the above, we can now see different sessions per JOB CYCLE. This will consume less resources and we solved the red nasty warnings in NHProf.

Mathew pointed out that we can go further, and optimised the 3 transactions above to be called in BATCH. So we can optimise the QueryOver methods to use Future operations, which will then batch the 3 transactions, which I can then use from within the job process, thus reducing each job cycle from 3 database calls to 1.

What i did was use something along the line of Future in my code and then delay looping through my result set until the last minute, so some code shuffling around Smile

 return Session.QueryOver<RomikoTable1>()
                .Where(x => x.CreatedDate >= RegDate
                    && x.CreatedDate <= dateUnreg
                    && x.Count == pollCount
                    && x.BobTheBuilder == null)
                .JoinQueryOver(y => y.TableTwo)
                .JoinQueryOver(z => z.PostManPat).Where(a => a.Id == PostManPatId)
                .Future<RomikoTable1>();

 

Now check the BATCHING, hence less connections, notice duration is for all of them, where before you see a duration for each query.

image

 

I would like to thank Matthew Wills for show me some new cool tools that will definitely help me along the road in the future!

I would say that NHProf is definitely worth buying!

Advertisements

One thought on “NHibernate/NHProf Dependency Injection and Sessions

  1. That is Matthew Wills, with two Ts. 🙂

    As I said to you earlier, anyone working with EF / NHibernate etc without one of Oren’s profilers is literally burning their employer’s / client’s money. They really are amazing in the insight in what they provide.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s