views:

214

answers:

2

I was in a ASP.NET application has heavy traffic of AJAX requests.

Once a user login our web application, a session is created to store information of this user's state. Currently, our solution to keep session data consistent is quite simple and brutal: each request needs to acquire a exclusive lock before being processed.

This works fine for tradition web application. But, when the web application turns to support AJAX, it turns to not efficient. It is quite possible that multiple AJAX requests are sent to server at the same time without reloading the web page. If all AJAX requests are serialized by the exclusive lock, the response is not so quick. Anyway, many AJAX requests that doesn't access same session variables are blocked as well.

If we don't have a exclusive lock for each requests, then we need to treat all race condition carefully to avoid dead lock. I'm afraid that would make the code complex and buggy.

So, is there any best practice to keep session data consistent and keep code simple and clean?

A: 

I give you a general idea for solving this problem.

Use Mutex, and for mutex name, use the session id.

The mutex lock base on the name that you give, so you avoid the conflict between your sessions.

a simple example http://aspalliance.com/290

Mutex vs Lock

Here is some answers
http://stackoverflow.com/questions/1164038/monitor-vs-mutex-in-c

http://stackoverflow.com/questions/301160/what-are-the-differences-between-various-threading-synchronization-options-in-c

in you case, if you use as Mutex name the session ID, then is going to lock with this name. People from different sessions id, will not be locked out, and you lock only the same people from the same session id.

You describe that a user of you can lock down all users, so with Mutex(sessionid) this is not going to happens.

Many pools, in the same server

Mutex is just fine, if you run on the same server.

Many WebServers

If you won to synchronize different web server, you need to have a common base, ether a common database, either a common directory that can read, write, lock, etc.

For the common directory:
In this case I do not know if you can create a mutex using a name like .\SharedDir\MutexSessionId1, but if you can not then you can make something similar by your self by creating and locking file names, after your work is done you delete them, the lock of the file is the lock you ask for.

For the common database:
You can create a table that you can use to lock and synchronize your actions, making somthing similar that the one that mutex do.

Aristos
Excuse me, what's the advantage of Mutex(mutual exclusive) than a lock?
Morgan Cheng
There is not advantage, there are different, I think that mutex is the one that you must use in your case, I update my answer for more details.
Aristos
of course maybe I did not understand all very well, I believe that you use the sessions from the asp.net (or not ?)
Aristos
@Aristos, thanks for your update.My web application actually doesn't use session from ASP.NET. It use its own customized session(due to legacy issue).
Morgan Cheng
@Aristos, in my understanding, Mutex has only unique ID in one machine. What if there is multiple web servers deployed and front end load balancer distributes request to any web server? Does Mutex prevent two requests from being handled at the same time?
Morgan Cheng
@Morgan I have update my answer, on multiple web server you need a shared directory, that inside you use files for lock unlock, ether by mutex, ether by just open and lock the files. For file name you use again the session id, or the Ip of your user for sure in case that did not use cookies
Aristos
+1  A: 

Once a user login our web application, a session is created to store information of this user's state. Currently, our solution to keep session data consistent is quite simple and brutal: each request needs to acquire a exclusive lock before being processed"

"Our solution" would imply that you are not using SessionStateModule and using a custom solution. In any case if you are using the default "Session" object provided by ASP.NET it already has the lock functionality and there's no need to implement it again.

ASP.net provides a marker interface IReadOnlySessionState to indicate that particular request needs only read access to the session (and thus the session is not locked for that particular request). Click here and navigate to "Concurrent requests and session state" section to find more details

Now, coming to your question, the way to use this marker interface for AJAX server side page method is setting the Page's property EnableSessionState to "ReadOnly".

If you are using AJAX Pro, you can use AjaxPro.AjaxMethod(HttpSessionRequirement.ReadOnly) attribute on your method.

kdhamane
Yes, the web app doesn't use Session provided by ASP.NET, even though it is built on ASP.NET.In my understanding, page with "EnableSessionState=Readonly" still waits for page that need to write to session. It just doesn't wait for pages also have "EnableSessionState=Readonly", right?If AJAX request needs to update session state(POST method), it still need to acquire the lock. Is that correct?
Morgan Cheng
Yes. Thats correct. In which case "EnableSessionState" will be true.By "web app doesn't use Session provided by ASP.NET", you mean the application doesn't use HttpContext.Session or Page.Session at all?. If that is the case you will need to the locking yourself and your pages or the ajax methods will have to explicitly tell whether they need read or write access (akin to Page.EnableSessionState property)However, if you are using HttpContext.Session, explicit locking need not be done. See the answer to the last question at this link: http://www.eggheadcafe.com/articles/20021016.asp
kdhamane