MVC属性中的HttpContext - 线程问题?

Rod*_*257 4 nhibernate asp.net-mvc httpcontext

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

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

                                NHibernateSessionManager.Instance.CloseSession();
                            };
    }
Run Code Online (Sandbox Code Playgroud)

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

public class TransactionAttribute:ActionFilterAttribute {private 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以将[Transaction]添加到我的action方法中.这似乎适用于初始测试,但我尝试在HttpWebRequest使用多次从另一个应用程序调用一个动作方法,我遇到了问题.使用Fiddler进行测试我设置了一个POST请求,然后快速连续关闭它们,它显示以下内容: WebRequests

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

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

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

因此,为了修复它,我将我的事务代码移动到我的BeginRequest和EndRequest方法中 - 然后我可以连续启动堆.

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

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

有人可以开导我吗?

Dar*_*rov 5

引用ASP.NET MVC 3发行说明:

在以前版本的ASP.NET MVC中,除少数情况外,每个请求都创建了操作过滤器.这种行为从来都不是保证行为,而只是一个实现细节,而过滤器的合同是将它们视为无状态.在ASP.NET MVC 3中,过滤器被更积极地缓存.因此,任何不正确地存储实例状态的自定义操作过滤器都可能被破坏.

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