views:

51

answers:

3

I have a legacy ASP.NET application in which there are some session/concurrency related issues and inconsistency.

I am looking for the best way to do the re-design/

This is the scenario A. Multiple users can log on to the site and access/modify a Ticket's details. However, if a user is already in the process of altering the workflow...the TicketId,UserId are stored in the DB with a time stamp.

B. If another user tries to access the same Ticket while its already being worked upon by a different user. Then, data is accessed from the DB and the most recent user is given a info-box saying that the Ticket is locked.

C. If the initial/locked-in user does a "Sign-Out" the lock is released in the DB. Now, the subsequent user can access with out hassle

All this fine...but if the initial user ..instead of "signing out"...just closes the browser window..the application still remains locked.

How to avoid this ? What is the best design in this scenario?

+2  A: 

This is called pesimistic concurrency. You can handle SessionEnd event (but only if you use InProc session) and release the lock on the ticket. The problem is that Session by default expires after 20 minutes. So if you really want to use pesimistic concurrency you have to make session as short as possible but this can affect current user - session can be lost during his work in browser. To avoid this implement javascript timer and some ping javascript / ajax operation which will keep your session alive while the user has the browser opened. If he close the browser without releasing ticket session will expire quickly. There is still disadvantage - if your user close browser and after a while opens new one all his session data will be lost.

Edit: Also this solution does not handle situation where user opens browser, locks the ticket and goes away for 2 hours lunch. If you also want to handle this solution you can combine it with some timeout on ticket activity.

Ladislav Mrnka
I believe many websites do this... using "keep alive" pings to the server.
Polaris878
A: 

It seems to me that the best thing you could do is build in a make-shift session timeout. When a ticket becomes locked, you can stamp it with the time it was locked. Whenever another person attempts to access this ticket, you can check to see not only if it was locked, but also when it was locked and if it was locked more than oh...let's say 5 hours ago, you can prompt the user to unlock the ticket, but lose the previous users modifications.

You could roll all kinds of role-based logic into it also and only give certain people the rights to unlock an expired editing session etc.

fdfrye
A: 

Unfortunately you have no other option just to time-out a 'lock'. Since the link between the Browser and the server is not a durable/reliable one, you cannot really detect all the ways that the user has abandoned the work, including abrupt browser close, client broadband modem reset, network outage or power interrupts. So all you can do is to have the 'locks' placed on the items have a time-out. IF the user does not complete the work in, say 30 minute, the item is returned to the pool of available items. This 'return' does not have to be an active operation, it can be implicit: the act of 'locking', or reserving, a work item adds a timestamp of UTCNOW() + 30 minutes. Any item with the timestamp in the past is good for grabs and considered unlocked (ie. the user did not finish working on it for 30 minutes). If the user returns from lunch and tries to finish the work after 45 minutes, you refuse the submitting and ask him to start anew. If the user refreshes the work periodically (say it saves every 10 minutes) perhaps it can extend the 'lock' with a fresh new 30 minutes period.

For this kind of patterns you should look into Using Tables as Queues.

Remus Rusanu