NHibernate leaking connections with UnitOfWork pattern and transactions

Recently I’ve been using NHibernate in a project at work along with the unit of work pattern in an asp.net mvc site. Only 1 instance of the UoW is created per request and disposed of at end of the request.

In fact here is a UoW class we’re using:

public class UnitOfWork : INHibernateUnitOfWork
  {
    /// <summary>
    /// The session factory
    /// </summary>
    private readonly ISessionFactory sessionFactory;

    /// <summary>
    /// The current transaction
    /// </summary>
    private readonly ITransaction transaction;

    /// <summary>
    /// Gets the session.
    /// </summary>
    /// <value>The session.</value>
    public ISession Session { get; private set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="UnitOfWork"/> class.
    /// </summary>
    /// <param name="sessionFactory">The session factory.</param>
    public UnitOfWork(ISessionFactory sessionFactory)
    {
      this.sessionFactory = sessionFactory;

      Session = this.sessionFactory.OpenSession();
      Session.FlushMode = FlushMode.Auto;
      transaction = Session.BeginTransaction();
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
      transaction.Dispose();
    }

    /// <summary>
    /// Commits this instance.
    /// </summary>
    public void Commit()
    {
      if (!transaction.IsActive)
      {
        throw new InvalidOperationException("No active transation");
      }

     /transaction.Commit();
    }

    /// <summary>
    /// Rollbacks this instance.
    /// </summary>
    public void Rollback()
    {
      if (transaction.IsActive)
      {
        transaction.Rollback();
      }
    }
  }

As you can see in the constructor we create a new NHibernate transaction and dispose of it when the request ends (by calling the dispose method).

The problem with this is that it created a connection with an open transaction but never closed it. Any way to resolve this we removed the use of transactions (until such a time they are working or we’ve figured out a suitable alternative). Two changes where made to the dispose and commit method to clean up the session instance and make sure the data is flushed.

    public void Dispose()
    {
      Session.Dispose();
    }

    public void Commit()
    {
      Session.Flush();
    }

Note: This project also is using the Velocity cache provider and by removing the transactions / replacing the code the caching mechanisms still work.

7 Comments

  • Pingback: How I fixed FluentNHibernate.Cfg.FluentConfigurationException on MVC 3 | Tony Williams Blog

  • March 15, 2012 - 8:47 am | Permalink

    Hi Tony,

    Did you manage to resolve this or did you stick with the solution your mentioned in your post? I have noticed the same problem in my own solution that connections are being leaked and the app keeps falling over because it uses all connections in the connection pool.

    Thanks, Simon

    • March 15, 2012 - 9:16 am | Permalink

      Yeah I managed to get this fixed, I really should do an update about this. What I did is this modify when the transaction was created by following this exmaple . I’ve also created an attribute so I don;t have to manual create the UoW for every request – I’ll post that bit up later on.

  • Pingback: Unit of Work, NHibnernate and Asp.Net MVC | Tony Williams

  • raholptl
    January 17, 2013 - 8:45 am | Permalink

    Hi Tony, Can you please share your code?

  • January 17, 2013 - 9:49 am | Permalink

    Which code? The code above is the one I use.

  • Leave a Reply