views:

18

answers:

1

I am using an HttpModule for handling my NHibernate Sessions and Transactions. I have many pages that are being very cranky about transactions not successfully starting on my IIS6 box but not when I run them locally, specifically when I try to call Commit() on the transactions during a PostBack to refresh datagrids with new updated data. These errors do NOT occur when I am debugging the code locally.

The web.config files for the local and the server are the same.

Is there some configuration on the server that could be causing behavioral differences with the module on IIS that my local VS Debug Server handles happily?

The module code looks like this:

public class NHibernateSessionModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += BeginTransaction;
        context.EndRequest += CommitAndCloseSession;
    }

    private static void BeginTransaction(object sender, EventArgs e)
    {
        if (HttpContext.Current.Request.RawUrl.Contains(".aspx"))
        {
            NHibernateSessionManager.Instance.InitSessionFactory();
            NHibernateSessionManager.Instance.BeginTransaction();
        }
    }

    private static void CommitAndCloseSession(object sender, EventArgs e)
    {
        if (HttpContext.Current.Request.RawUrl.Contains(".aspx"))
        {
            try
            {
                NHibernateSessionManager.Instance.FlushSession();
                NHibernateSessionManager.Instance.CommitTransaction();
            }
            finally
            {
                NHibernateSessionManager.Instance.CloseSession();
            }
        }
    }

    public void Dispose() { }
}

The relevant manager code is as follows:

    private void InitSessionFactory()
    {
        if (sessionFactory != null)
        {
            return;
        }

        var cfg = new Configuration();

        // The following makes sure the the web.config contains a declaration for the HBM_ASSEMBLY appSetting
        if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["HBM_ASSEMBLY"]))
        {
            throw new ConfigurationErrorsException(
                "NHibernateManager.InitSessionFactory: \"HBM_ASSEMBLY\" must be " +
                "provided as an appSetting within your config file. \"HBM_ASSEMBLY\" informs NHibernate which assembly " +
                "contains the HBM files. It is assumed that the HBM files are embedded resources. An example config " +
                "declaration is <add key=\"HBM_ASSEMBLY\" value=\"MyProject.Core\" />");
        }

        // Don't make session factories for foundations that share a database
        string hibernateString = BaseAccess.GetHibernateConnectionString();


        cfg.AddAssembly(ConfigurationManager.AppSettings["HBM_ASSEMBLY"]);
        cfg.SetProperty("connection.connection_string", hibernateString);
        sessionFactory = cfg.BuildSessionFactory();
    }

    public void BeginTransaction()
    {
        if (threadTransaction == null ||
            threadTransaction.WasCommitted ||
            threadTransaction.WasRolledBack ||
            !threadTransaction.IsActive)
        {
            threadTransaction = GetSession().BeginTransaction();
        }
    }

    public ISession GetSession()
    {
        if (null == sessionFactory)
        {
            InitSessionFactory();
        }

        if ((threadSession == null || !threadSession.IsOpen) && null != sessionFactory)
        {
            threadSession = sessionFactory.OpenSession();
        }

        return threadSession;
    }

    private void FlushSession()
    {
        if (null != threadSession && threadSession.IsOpen)
        {
            threadSession.Flush();
        }
    }

    public void CommitTransaction()
    {
        try
        {
            if (threadTransaction!= null && !threadTransaction.WasCommitted && !threadTransaction.WasRolledBack && threadTransaction.IsActive)
            {
                threadTransaction.Commit();
                threadTransaction = null
            }
        }
        catch (HibernateException)
        {
            RollbackTransaction();
            throw;
        }
    }

    public void RollbackTransaction()
    {
        try
        {
            if (threadTransaction != null && !threadTransaction.WasCommitted && !threadTransaction.WasRolledBack && threadTransaction.IsActive)
            {
                threadTransaction.Rollback();
            }
        }
        finally
        {
            CloseSession();
        }
    }

    private void CloseSession()
    {
        if (threadSession != null && threadSession.IsOpen)
        {
            threadSession.Close();
        }
    }
+1  A: 

A guess because the complete code is not included: You store the session in the thread and the threading behaves different? You should store the session in the httpcontext and it will probably be fine.

Paco
I moved the sessions and threads into HttpContext.Current.Items and the exact same behavior is occurring.
mikeschuld
Can you show some more code so to reproduce the error?
Paco