HttpContext in MVC attributes - threading issues?

I had a NHibernate session management setup, as shown below:

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

And when I needed to save the database, I created an ActionFilterAttribute that looked like this:

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

and then I can just add [Transaction] to my action method. This seemed to work during the initial testing, but then I tried to use the HttpWebRequest several times to call the action method from another application, and I had problems. Testing with Fiddler, I installed a POST request, and then quickly worked them out, and the following appeared: Webrequests

Reds are different errors that I think are related to stream processing.

My NHibernateSessionManager uses an HTtpContext to store the session as follows:

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

So, to fix this, I moved my transaction code to my BeginRequest and EndRequest methods, and then I was able to quickly remove heaps in a row.

My question is: why fix it? I would think that I would have something like this: Begin Request - opens the OnActionExecuting session - starts the transaction action code OnActionExecuted - completes the transaction End Request - closes the session

and that it will be unique for each request, therefore it should not interfere with each other, because for each request there should not be another HttpContext for each request? Or do they share or something?

Can someone enlighten me?

+4
source share
1 answer

Quote from the ASP.NET MVC 3 release note :

In previous versions of ASP.NET MVC, action filters were created per request, except in a few cases. This behavior was never guaranteed, but simply implementation in detail and the filter contract was to consider them stateless. In ASP.NET MVC 3, filters are cached more aggressively. Therefore, any custom action filters that improperly store the state of an instance may be compromised.

This basically means that the _currentTransaction instance that you have in your action filter may not be what you think. Therefore, be careful with how / when this property is entered => from the code you showed is unclear.

+5
source

Source: https://habr.com/ru/post/1343118/


All Articles