0

I am having trouble getting my head around optimistic locking. The framework I am using is Play 1.2.5.

Say I am selling concert tickets. I currently have the following:

if (concert.ticketsSold < concert.tickets) {
    concert.ticketsSold ++;
    concert.save();
}

However, when several people book at the same time, the ticketsSold counter "lags" behind the real sold value. Eg it will say 2500 when i fact I sold 2700.

This is when I started reading about OptimisticLockException. In all the examples I found on the interweb, people tend to catch the OptimisticLockException, and show an error to the user.

What I want, is for the system to retry a certain number of times, before showing the user an error. The code I wrote is as follows:

boolean saved = false;
int tries = 0;
while (!saved) {
    try {
        if (concert.ticketsSold < concert.tickets) {
            concert.ticketsSold ++;
            concert.save();
            saved = true;
        } else break;
    } catch (OptimisticLockException e) {
        // reload concert object from the database
        concert.refresh();
    }
    if (tries > 9) break;
    tries++;
}

As you see above, I try to reload the object from the database, to get the "updated" object, with the correct number of tickets sold, but whatever I try (refresh, reload, commit and begin new transaction), the object is not refreshed, and I still get the normal "cached" version of the object.

Any ideas on what I am doing wrong?

Many thanks!

Axel

PS: I am not using any caching system, like memchached or other.

Axxoul
  • 115
  • 1
  • 1
  • 6
  • These things are hard to test. Can you prove somehow that the number of tickets should have changed and what value should be? What code should be executed on `concert.refresh()`? – hotzst Oct 01 '15 at 08:40
  • Yes, the way I test is by setting a breakpoint after the model is fetched from the DB, then change in the DB the version number and the ticketsSold counter.. When the code runs, the new "updated" object is never fetched.. – Axxoul Oct 01 '15 at 08:48
  • Ha and refresh() is a standard method in JPA EntityManager: http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#refresh-java.lang.Object- – Axxoul Oct 01 '15 at 08:51
  • Seems that http://stackoverflow.com/questions/2400430/invalidating-jpa-entitymanager-session could be of some help here, will update this question if that is the case – Axxoul Oct 01 '15 at 08:52

0 Answers0