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();
}
}