【问题标题】:HttpContext in MVC Attributes - threading issues?MVC 属性中的 HttpContext - 线程问题?
【发布时间】:2011-03-10 06:01:03
【问题描述】:

我的 NHibernate 会话管理设置如下:

    protected MvcApplication()
    {
        BeginRequest += delegate
                            {
                                NHibernateSessionManager.Instance.OpenSession();
                             };
        EndRequest += delegate
                            {

                                NHibernateSessionManager.Instance.CloseSession();
                            };
    }

当我需要保存到数据库时,我创建了一个 ActionFilterAttribute,如下所示:

公共类TransactionAttribute:ActionFilterAttribute { 私有 ITransaction _currentTransaction;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _currentTransaction = NHibernateSessionManager.Instance.CurrentSession.Transaction;
        _currentTransaction.Begin();
    }


    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (_currentTransaction.IsActive)
        {
            if (filterContext.Exception == null)
                _currentTransaction.Commit();
            else
            {
                _currentTransaction.Rollback();
            }
        }
        _currentTransaction.Dispose();
    }
}

然后我可以将 [Transaction] 添加到我的操作方法中。这似乎在初始测试中有效,但后来我尝试使用 at HttpWebRequest 多次调用另一个应用程序的操作方法,但我遇到了问题。使用 Fiddler 进行测试,我设置了一个 POST 请求,然后快速触发它们,结果如下:

红色的是我认为与线程有关的各种错误。

我的 NHibernateSessionManager 使用 HTtpContext 来存储会话,如下所示:

    public ISession CurrentSession
    {
        get { return (ISession)HttpContext.Current.Items["current.session"]; }
        set { HttpContext.Current.Items["current.session"] = value; }
    }

因此,为了修复它,我将事务代码移到了 BeginRequest 和 EndRequest 方法中——然后我可以连续触发堆。

我的问题是 - 为什么要解决它?我原以为我会有类似的东西: 开始请求 - 打开会话 OnActionExecuting - 开始事务 动作代码 OnActionExecuted - 提交事务 结束请求 - 关闭会话

并且这对于每个请求都是唯一的,所以它不应该相互干扰,因为每个请求应该有一个不同的 HttpContext 不应该吗?或者他们是共享的还是什么?

有人可以启发我吗?

【问题讨论】:

    标签: asp.net-mvc nhibernate httpcontext


    【解决方案1】:

    引用自release notes of ASP.NET MVC 3

    在以前版本的 ASP.NET MVC 中, 动作过滤器是根据创建的 除少数情况外要求。这 行为从来都不是保证 行为,但仅仅是一种实现 详细信息和过滤器合同 是认为他们无国籍。在 ASP.NET MVC 3,过滤器缓存更多 积极地。因此,任何习俗 不正确存储的动作过滤器 实例状态可能被破坏。

    这基本上意味着您在操作过滤器中拥有的_currentTransaction 实例可能不是您认为的那样。所以要小心这个属性是如何/何时注入的=>从你显示的代码中不清楚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      • 2012-04-14
      • 2016-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多