Optimistic Locking

#1

We are having problems with optimistic locking.

I made a simple test case to try to induce an optimistic lock.

I have two users logged on to our system.  They both read and display the same data.  Then I change the data with user 1 and submit, and then I change it with user 2 and submit.

User 2 does not get an optimistic lock exception, so the database has user 2’s change.

Do you have a simple test that demonstrates optimistic locking working?

#2

The following JDO 2 example demonstrates optimistic lock exception (it should work the same way also in JPA 2):

package com.objectdb.example;

import java.util.*;

import javax.jdo.*;
import javax.jdo.annotations.*;

public class OptimisticLockExceptionExample {

  public static void main(final String[] args) {
 
    // Create a new database:
    Properties properties = new Properties();
    properties.setProperty(
        "javax.jdo.PersistenceManagerFactoryClass", "com.objectdb.jdo.PMF");
    properties.setProperty("javax.jdo.option.ConnectionURL", "db.odb");
    PersistenceManagerFactory pmf =
        JDOHelper.getPersistenceManagerFactory(properties);

    // Persist one Counter object:
    PersistenceManager pm = pmf.getPersistenceManager();
    pm.currentTransaction().begin();
    pm.makePersistent(new Counter());
    pm.currentTransaction().commit();
    pm.close();

    // First user retrieves and updates the Counter:  
    PersistenceManager pm1 = pmf.getPersistenceManager();
    Counter c1 = pm1.getExtent(Counter.class).iterator().next();
    pm1.currentTransaction().begin();
    c1.increase();

    // Second user retrieves and updates the Counter:  
    PersistenceManager pm2 = pmf.getPersistenceManager();
    Counter c2 = pm2.getExtent(Counter.class).iterator().next();
    pm2.currentTransaction().begin();
    c2.increase();

    // First user commits - succeeds:  
    pm1.currentTransaction().commit();
    pm1.close();

    // Second user commits - fails with JDOOptimisticVerificationException:  
    pm2.currentTransaction().commit();
    pm2.close();

    // Close the database:
    pmf.close();
  }

  @PersistenceCapable
  static class Counter {
    private int count;
    void increase() {
      count++;
    }
  }
}

For optimistic locking to work each user should have its own PersistenceManager and the update must be based on the object that was retrieved from the database.

For example, if you retrieve an object, copy its data to a temporary data structure for presentation and then on update retrieves the object again and fills its with the data from the temporary data structure - then updates of other users might be overridden.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)

Post Reply

To post a reply and/or subscribe to update notifications - please login