views:

44

answers:

1

I have got an odd problem with NHIbernate, and seeing as this is my first NHIbernate project I thought I'd ask the good people of StackOverflow.com.

I'm following the 'Open session in view' pattern in ASP.Net, which opens a hibernate transaction on each request and commits it at the end of the request.

This works fine normally, however on one of my pages, which is simply a read page not a write one, I get an issue. The page in question gets a list of projects, and does a few queries for information based on them.

As a part of that, it calls an external DLL, which has an SQL Query to a database inside of it. This call appears to work for all projects except for one, where it gets a timeout on the ExecuteReader() call.

After trying to find a bug in the external DLl for some time, I decide to comment out the establishing of the transaction inside of the http handler.This fixed the issue.

So, somehow hibernates session management is affecting external, unrelated (well, there is a chance that some of the mappings touch the same databases that are used in that query, however its read only on both ends)

My question is, why is it doing this? What is nhibernate doing under the hood that causes other SQL queries to timeout? I take it it has a lock on some part of the database, but why is it doing that if the page only reads? How can I get around this?

edit: following parts of this guide http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

More info: I have a IHttpModule that does the following in BeginRequest

private void BeginTransaction(object sender, EventArgs e)
    {
        Console.WriteLine("Begin Transaction");
      NHibernateSessionManager.Instance.BeginTransaction();
    }

then on close

  private void CommitAndCloseSession(object sender, EventArgs e)
    {
    Console.WriteLine("End Transaction");
    try
    {

        NHibernateSessionManager.Instance.CommitTransaction();
    }
    finally
    {
        NHibernateSessionManager.Instance.CloseSession();
    }
}

The NHIbernateSEssionManager does this: - stores an ITransaction + ISession in the HTTPContext. These are accessible as proprties named ContextTransaction and ContextSession. These are used in:

   public void BeginTransaction()
        {
            ITransaction transaction = ContextTransaction;

            if (transaction == null)
            {
                transaction = GetSession().BeginTransaction();
                ContextTransaction = transaction;
            }
        }

     public void CommitTransaction()
        {
            ITransaction transaction = ContextTransaction;

            try
            {
                if (HasOpenTransaction())
                {
                    transaction.Commit();
                    ContextTransaction = null;
                }
            }
            catch (HibernateException)
            {
                RollbackTransaction();
                throw;
            }
        }
A: 

From the sound of it I'd guess that there is an ambient distributed transaction which causes the cross-impacts. Are you using the TransactionScope class for managing the transactions?

Lucero
Read the documentation.
TomTom
TomTom, that's not helpful, thanks. @Lucero thanks for your answer, I'm not using TransactionScope explicitly (I've updated main post with code), doesn't NHibernate have transaction support built in? Or are you saying I should use transactionscope in the separate DLL?
RodH257