Ideally, ASP.NET performs a single read and single write on a serialized collection of the objects stored in the user's session once on each request (e.g. page/controller). If you access multiple items from that collection on a request, it uses the local copy and will not have to access the underlying datastore.
However, what I think you are noticing is ASP.NET's pessimistic locking model. When it attempts to perform the single read to retrieve the user's session data, if that user's session data has a lock set on it already, it will continually retry to retrieve it (every 500 milliseconds).
The specifics of your ASP.NET HTTP lifecycle depend on framework version, etc, but the general concept is something like this:
- Set exclusive lock on row containing session's data in datastore (If exclusive lock cannot be obtained, wait until it can)
- Read/deserialize collection from datastore row for this session
- Execute your page/controller
- Serialize/write collection back to datastore
- Remove exclusive lock
If you have multiple HTTP requests accessing a user's session (e.g. Ajax on a page) you will notice there is no concurrency because of exclusive locks - they execute serially if Session
is enabled for each one. (even if they do not explicitly access Session
).
One way to avoid this is to be intentional about where you write to Session
, and on all other pages/controllers specify SessionStateBehavior.ReadOnly
. When you do so, ASP.NET will not set an exclusive lock (will use GetItem instead of GetItemEx). See ASP.NET Session State Overview.
Page:
<% @Page EnableSessionState="ReadOnly" %>
Controller:
[SessionState(SessionStateBehavior.ReadOnly)]
Reference:
Hope this helps!
Regards,
Ross