Tag Archives: Pattern

Asp.Net MVC Code

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.