4

I recently discovered that when you have a page set to session readonly and you are using inproc (in memory) session storage, the session is still writable on that page and is not truly read only. Out of process session storage does respect the readonly setting.

Do you still get the benefit of having no session lock contention when a page is set to readonly and using inproc mode? Will multiple simultaneous requests with the same session Id have to wait for the session lock to release when in readonly and inproc?

james2code
  • 894
  • 10
  • 19

2 Answers2

9

See this blog post: Handling multiple simultaneous requests from a user in ASP.NET:

  • enableSessionState="true" is the default behavior, and acquires a writer lock on session data. No other readers or writers can gain access while this lock is held.

  • enableSessionState="ReadOnly" acquires a reader lock on session data. Multiple readers are allowed simultaneously, but no writer can gain access if any reader holds a lock. Unfortunately, any changes you make to session are local to the request and not visible to other requests that look at the session object. No error is thrown if you try to modify a "read only" session, so this behavior is not obvious at first blush.

  • enableSessionState="false" doesn't acquire any lock. The HttpContext.Session property ends up being null, and your page will have no access to session data.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Yiping
  • 91
  • 1
  • 1
6

BuzzAnn,

Microsoft's documentation on the topic indicates that setting your page-level session state mode to "ReadOnly" should safeguard you against concurrent attempts to write session state information (they'll queue and be handled serially), but multiple readers will be allowed. See the "Synchronizing Access to the Session State" section:

http://msdn.microsoft.com/en-us/library/aa479041.aspx

When the EnableSessionState property for a page is set to "ReadOnly," each page request attempts to get a reader lock on the state information. In standard ReaderWriterLock semantics, any number of readers can have concurrent access to the information being protected. Any request that achieves a writer lock (e.g., through EnableSessionState being set to "true"), though, will block writes and reads on the session state information until the request holding the writer lock completes.

As long as all you're trying to do is read session state information from your pages while they have EnableSessionState set to "ReadOnly," all read requests will proceed without blocking. If you attempt to write, though, the documentation isn't clear about what will actually happen. Assuming a ReaderWriterLock is all that's being used to synchronize access, my guess is that you won't be protected against overwrites, race conditions, and other non-synchronized access problems.

If you're going to attempt to write to session state, be sure to set EnableSessionState to "true" to ensure that a writer lock is achieved and synchronization occurs as is needed.

I hope this helps!

Sean P. McDonough
  • 2,426
  • 1
  • 15
  • 11
  • It really is not clear what happens though for inproc only. Does it still actually use reader\writer locking for inproc since it doesn't follow the readonly setting with inproc. The only bit of info I have found is from http://www.syncfusion.com/faq/aspnet/web_c9c.aspx which states: "Even those enableSessionState is marked as ReadOnly, but in InProc state, the user can still modify the session. The only difference is that the session will not be locked during the request. This limitation is by-design" – james2code Aug 26 '09 at 03:26
  • The text block you cited from SyncFusion is consistent with what I would expect based on ReaderWriterLock semantics. Setting the EnableSessionState mode to "ReadOnly" doesn't *make it* read only for InProc; rather, you're indicating (to ASP.NET) that you *intend* to use it in a read-only fashion. The "ReadOnly" mode is less restrictive than the "true" mode and only guarantees that you won't collide with other changes being made by pages that have an EnableSessionState of "true." Trying to modify session state from a page in "ReadOnly" mode remains a hazardous proposition. Does that help? – Sean P. McDonough Aug 26 '09 at 15:27
  • Yes, that helps. So what you are saying is that locking still occurs even with InProc. Whether it be readonly with reader locks or "true" with writer locks. I agree it is hazardous to try and make all pages readonly in inproc mode while still writing to the session on those pages. However it was suggested as an option by a coworker and I am trying to determine if doing that solves the lock contention problem without having to change all the code to not write to sessions. We have a tiny percentage of requests that get blocked for 2 minutes while waiting on a request that never finished.Thx – james2code Aug 26 '09 at 20:45
  • Actually, the session is not locked for readonly and inproc. We wrote a test program that verified this. – james2code Sep 02 '09 at 23:16
  • When you say the session is "not locked," what exactly do you mean (that is, what was the hypothesis of your test)? Were you testing read/write behavior to the session, or are you speaking about the InProc ReaderWriterLock that the documentation indicates is used? – Sean P. McDonough Sep 03 '09 at 01:58
  • I mean no locking occurs at all whether you are writing to the session or not. So if the page that is set to readonly writes to the session, it will not block any other simultaneous requests that are trying to write to the session. What we did for the test was send a first request that did not contain the full request body. IIS hands the request off to ASP.Net and it starts going through the pipeline modules even though it still does not yet have the full request (An apparent ASP.net optimization). It makes it past the session module at that point. See next comment. – james2code Sep 09 '09 at 01:41
  • The session module checks how it is supposed to handle session locking via the page properties. In our test, we would send the first bad request and then 10 good requests. If session readonly was set, all the requests would be processed immediately even though we were writing to the session on the first request. If the first request was not set to readonly, all the requests would wait until the timeout occurred on the first request (Since the first request had made it passed the session module locking the session, while not finishing because of not having the full request body). – james2code Sep 09 '09 at 01:50
  • The original reason we were pursuing this was trying to get past the 200+ requests a day (out of 500k) that are causing a few users to have bad experiences. We were seeing this mainly from satellite internet and wireless customers. However, trying the readonly\inproc idea was just a test. I do not feel it is prudent and is hazardous as you mentioned before. It was just suggested as an option and we had to pursue but are not likely to implement. – james2code Sep 09 '09 at 01:57