views:

1013

answers:

5

User A logs into a ticket management system to edit content on "SomePage.aspx"

User B logs in 30 seconds later to edit the same ticket on "SomePage.aspx"

What are some of the best known practices(in a 3-tier architecture) for notifying each of the users that someone else is modifying the same content?

+4  A: 

In a request/response system like HTTP, there isn't much of a concept of what a user is currently doing. You could notify them that someone else opened the ticket for edit "within the last two minutes" (or even prevent them from opening it in such a case) but user A could edit for half an hour - unless you prohibit that as well. You could keep a note of the fact that you believe user A has effectively "got" the item for edit, but with a web app there's nothing to stop the user from just walking away from the computer and never either saving/canceling.

Before thinking about the technological solutions, I suggest thinking about the technological restrictions (the asynchronous and request/response nature of the web, basically) and work out the desired behaviour. Some common behaviours are:

  • First edit wins (tell second editor that their changes have been rejected, basically)
  • Second edit wins (overwrite first edit - it's too late to tell the first editor)
  • Merge (can be insanely difficult and/or impossible, depending on the content). This may be automatic or manual (on the part of the second editor).
  • Prevent a second person from editing while you think a first person may be editing (rarely appropriate for web apps due to the issue mentioned in the first paragraph)
Jon Skeet
You missed Pessimistic Concurrency (i.e., locking so that user B isn't even allowed to begin the editing process).
Brad Wilson
Pessimistic Concurrency can be an option, but it can be really hard to maintain especially in a disconnected environment like HTTP. You're forced to constantly notifies the server about the current state of user screen. Multiple tab scenario is also something to tackle.
Salamander2007
@Brad: I'd count that as part of "or even prevent them from opening it in such a case" - note that I'm not trying to address *how* the results should be achieved, just "work out what you want to happen before you start coding".
Jon Skeet
@Brad: Added a bit more information in the first paragraph and added the fourth bullet to cover this more.
Jon Skeet
There are some variations on the 'First edit wins' option allowing the second editor to manually do the merge.
Timbo
@Timbo: Edited to reflect option of manual merge.
Jon Skeet
A: 

i'm assuming that you're talking about a help-desk ticket or something analgous, where only one user should be working on it at a time. In this case the status of the ticket should change when the first user checks it out

Steven A. Lowe
+1  A: 

I'm not very experienced on this but if I need to do something like that, I would create a new field on the database on the Ticket Table called EditingBy and add a default value of '0'.

when a user calls the TicketID = 897 the query should be like:

SELECT * FROM Tickets WHERE TicketID = 897; 
UPDATE Tickets SET EditingBy = @UserID WHERE TicketID = 897;

then in the code, you see if the EditingBy is greater than 0 you can warn UserB that UserA (you know the UserID) is editing the ticket, like SO does when someone post an answer and you are writing yours, or when you get a new badge for example.

when commit the ticket for update you can then update the field back to 0.

and be advise that the user can enter the SomePage.aspx and leave without doing anything, for that a javascript onUnload in the body tag that would trigger an Asynchronous call to update the EdittingBy back to 0 would be an idea.

hop that this gives you an idea about doing it.

Edited: you can always record the EditingBy in a XML file if you can't edit the Database itself, just keep TicketID and UserID, and instead of finding if it is greater than 0, just check if the TicketID is in the XML.

balexandre
I'm not sure the javascript onUnload event can be relied on to always fire. Can anyone else confirm/dismiss?
CJM
you can test it yourself :-)<html> <head> </head> <body onunload="alert('The onunload event was triggered')"> Leave the page in any way you want </body><html>
balexandre
+2  A: 

Roundup uses (for example) the optimistic concurrency approach: when you submit your change you may see a warning that someone has made changes before you, with a link to a page showing their changes. You can click Submit to just carry on with your change or edit the values in the form and then submit.

This works OK for a ticketing system because there is little shared state on a ticket -- mostly you append to the message log (or equivalent), so the 2 messages get added one after the other.

pdc
A: 

@Jon Skeet: Thanks for the detail and optional approaches

@pdc: Thanks for the most focused approach.

deadbug