Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

Panel

Example Situation

To set the scene, here's a typical situation in our web applications:

  • David pulls up data in his browser. Goes to lunch.
  • Felicia pulls up same data, makes a change and saves. Changes Felicia's changes are committed to the DB.
  • David comes back from lunch, changes the data on his screen and saves. Changes David's changes are committed, overwriting Felicia's changes.

Obviously this isn't good; when David finally submits changes, we need the app to detect that someone else has changed the data, and to handle the situation appropriately. Two aspects to doing this are:

  1. Detection - how to detect a concurrent update
  2. Handling - what to do if we detect a concurrent update

We'll take these in reverse order:

Panel

Handling a Concurrent Update Situation

There are three approaches to handling a concurrent update situation:

  1. Last commit wins. This is the situation described above, where David wipes out Felicia's changes. This is what we're doing most of the time in our apps, and it does not involve any detection of a concurrent update.
  2. First commit wins. In this scenario, David would come back from lunch, attempt to save his changes, and see an error message "Someone else has changed the data. Your changes have not been saved". David's changes would not be saved to the DB. This does require detection of a concurrent update.
  3. Merge. Here, David would be presented with a message telling him that someone else had changed the data, and would be provided with a UI to give them him a way of merging his changes with Felicia's changes. This does require detection of a concurrent update.

Unless there's a clear business requirement for the merge option, I think we need to take the second approach, "first commit wins". In order to pursue this approach, we do need to have a mechanism for detecting concurrent updates. Which leads to...

...

Also there is a non-web project that uses a unit test \ [TestConcurrency.testConcurrentUpdate()\] to illustrate the concurrent update situation:

Panel

Chosen Solution

For Education Systems web apps we have decided to use detection option 1 - passing the version number to the JSP in the GET request, and moving the version number into the retrieved Hibernate entity during the POST request. Hibernate itself will then take care of checking version number on update. If a concurrency problem is encountered, Spring should throw a org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException. This exception should be intercepted by the web app and an appropriate UI action should take place (for example, forwarding to an error page, or displaying a message on the current page).

There is a simple web app demonstrating this scheme. It uses an in-memory H2 database so should be self-contained :

Code Block
svn+ssh://svn.mit.edu/csf-playground/web-concurrency

Wiki Markup
Code Block
svn+ssh://svn.mit.edu/csf-playground/hibernate-concurrency

NOTE: if the web page displays multiple objects that can be updated, the version numbers of all the objects must be included in the JSP, and must all be applied to the relevant entity objects when the form data is posted.

...