C# NHibernate会话/事务在IIS6和Visual Studio 2008调试服务器上的行为不同

C# NHibernate会话/事务在IIS6和Visual Studio 2008调试服务器上的行为不同,c#,visual-studio-2008,nhibernate,iis-6,C#,Visual Studio 2008,Nhibernate,Iis 6,我正在使用HttpModule来处理我的NHibernate会话和事务。我有很多页面都对没有在IIS6框上成功启动的事务非常恼火,但当我在本地运行它们时,尤其是当我在回发期间尝试调用事务的Commit()以使用新更新的数据刷新数据网格时,这些页面就不会这样。在本地调试代码时不会发生这些错误 本地和服务器的web.config文件相同 服务器上是否有一些配置可能会导致与我的本地VS Debug服务器处理的IIS上的模块的行为差异 模块代码如下所示: public class NHibernateS

我正在使用HttpModule来处理我的NHibernate会话和事务。我有很多页面都对没有在IIS6框上成功启动的事务非常恼火,但当我在本地运行它们时,尤其是当我在回发期间尝试调用事务的Commit()以使用新更新的数据刷新数据网格时,这些页面就不会这样。在本地调试代码时不会发生这些错误

本地和服务器的web.config文件相同

服务器上是否有一些配置可能会导致与我的本地VS Debug服务器处理的IIS上的模块的行为差异

模块代码如下所示:

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() { }
}
相关经理代码如下:

    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();
        }
    }
private void InitSessionFactory()
{
if(sessionFactory!=null)
{
返回;
}
var cfg=新配置();
//以下内容确保web.config包含HBM_程序集appSetting的声明
if(string.IsNullOrEmpty(ConfigurationManager.AppSettings[“HBM_ASSEMBLY”]))
{
抛出新的ConfigurationErrorsException(
“NHibernateManager.InitSessionFactory:\“HBM\U程序集\”必须是”+
“作为配置文件中的应用设置提供。\“HBM\U程序集\”通知NHibernate哪个程序集”+
“包含HBM文件。假定HBM文件是嵌入式资源。示例配置”+
“声明是”);
}
//不要为共享数据库的基金会创建会话工厂
字符串hibernateString=BaseAccess.GetHibernateConnectionString();
cfg.AddAssembly(ConfigurationManager.AppSettings[“HBM_ASSEMBLY”]);
SetProperty(“connection.connection_string”,hibernateString);
sessionFactory=cfg.BuildSessionFactory();
}
公共无效开始生效()
{
if(threadTransaction==null||
threadTransaction.WasCommitted||
threadTransaction.WasRolledBack||
!threadTransaction.IsActive)
{
threadTransaction=GetSession().BeginTransaction();
}
}
公共会话GetSession()
{
if(null==会话工厂)
{
InitSessionFactory();
}
if((threadSession==null | |!threadSession.IsOpen)&&null!=sessionFactory)
{
threadSession=sessionFactory.OpenSession();
}
返回会话;
}
私有void FlushSession()
{
if(null!=threadSession&&threadSession.IsOpen)
{
threadSession.Flush();
}
}
公共无效委托交易()
{
尝试
{
if(threadTransaction!=null&&!threadTransaction.WasCommitted&&!threadTransaction.WasRolledBack&&threadTransaction.IsActive)
{
提交();
threadTransaction=null
}
}
捕获(休眠异常)
{
回滚事务();
投掷;
}
}
公共无效回滚事务()
{
尝试
{
if(threadTransaction!=null&&!threadTransaction.WasCommitted&&!threadTransaction.WasRolledBack&&threadTransaction.IsActive)
{
threadTransaction.Rollback();
}
}
最后
{
CloseSession();
}
}
私有会话()
{
if(threadSession!=null&&threadSession.IsOpen)
{
threadSession.Close();
}
}

猜测,因为未包含完整的代码:
您将会话存储在线程中,线程的行为是否不同?您应该将会话存储在httpcontext中,它可能会很好。

通常是“事务未成功启动”我将会话和线程移动到HttpContext.Current.Items中,并且发生了完全相同的行为。移动到HttpContext和手动关闭并处理连接的组合似乎解决了此问题。我添加了一个块,用于在出现“Not Started”错误时启动事务,并且它似乎也捕获了需要在该上下文中发生的任何操作,因此现在一切都很好。