【问题标题】:Session was already closed in ASP .NET Session Per Request pattern会话已经在 ASP .NET Session Per Request 模式中关闭
【发布时间】:2012-11-02 18:37:19
【问题描述】:

我在 ASP .NET Web 窗体应用程序中使用 Session Per Request 方法。

这是请求结束时运行的代码,这是我关闭会话的方式:

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, SessionFactoryProvider.SessionFactory);

        if (session != null)
        {
            if (session.Transaction != null && session.Transaction.IsActive)
            {
                session.Transaction.Rollback();
            }
            if (session.IsOpen)
            {
                session.Close();    
            }
        }
    }

很明显的东西。但是,我在调用 session.Close 时经常遇到异常。异常是 SessionException 类型,消息是:

{“会话已经关闭”}

堆栈跟踪是:

   at NHibernate.Impl.SessionImpl.Close() in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 343

我使用的 NHibernate 版本是:3.0.0.4000

我已经搜索过可以关闭会话的代码,但没有找到。此外,我还使用与会话对象无关的简单请求对其进行了测试,并且仍然相同。有什么想法可能是什么问题?

编辑:在分而治之的会议之后,我已经针对导致该异常的一段代码

                    var session = SessionFactoryProvider.GetCurrentSession();
                    using (ITransaction tx = session.BeginTransaction())
                    {
                        session.Update(instrument);
                        tx.Commit();
                    }

如果我将其注释掉,则会话在 EndRequest 处理程序中顺利关闭,并且不会引发 会话已关闭 异常。

【问题讨论】:

  • ISession 是 IDisposable,因此您应该更愿意在其上调用 Dispose()。那个版本的NH真的很老了,也是NH 3系列的第一部,也许你应该尝试升级一下。
  • 谢谢。我使用了 Dispose 仍然是一样的。我设法发现的是,显式事务会导致问题。我会更新问题。
  • 这很奇怪......事务应该总是“显式”以获得最佳兼容性,所以这个故事肯定有更多内容。
  • 可能有一些错误处理程序会关闭会话?
  • 我不这么认为。我从第一行代码编写了那个应用程序:)

标签: asp.net nhibernate ado.net


【解决方案1】:

我们正在使用IHttpModule,这样:

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

        private void CommitAndCloseSession(object sender, EventArgs e)
        {
            // commit or rollback depending on errors
            // then close session
        }

        ...
}

在 web.config 中

<httpModules>
    <add name="NHibernateSessionModule" type="XXX.ModuleSessionNHibernate, XXX"/>
</httpModules>

编辑:关于提交和关闭会话(但我们使用了大量的 Helper 和 Services...)

    private void CommitAndCloseSession(object sender, EventArgs e)
    {
        try
        {
            if (no exception in context)
            {
                // commit transaction
            }
            else
            {
                // rollback transaction
            }
        }
        finally
        {
            try
            {
                // close session
            }
            catch (Exception ex)
            {
                // send email                       
            }

                // rollback
                // close

                throw;
            }
        }
    }

【讨论】:

  • 好吧,但是 BeginTransaction / CommitAndCloseSession 是什么样子的?基本上这是有趣的部分。无论您使用 Global .asax 还是 IHttpModule 都只是方法和关注点分离的问题 - 当然您的方法更好:)
  • 我更新了我的帖子,但由于我们使用了很多帮助和东西,它可能对你没有太大帮助。我认为大多数处理 sessionNhibernate 方法的背后。
【解决方案2】:

问题已通过迁移到 NHibernate 3.3.1 得到解决。

但是,其他问题浮出水面:

Could not find the property - exception after switching from NHibernate 3 to 3.3.1

【讨论】:

    猜你喜欢
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 2011-04-29
    • 2011-09-08
    相关资源
    最近更新 更多