Slim3 Datastore‎ > ‎Transactions‎ > ‎

Optimistic Locking with version property

The datastore supports transaction for entity group, so if you update a model inside a transaction and another request commits an update to same model or some other model in the same entity group before you commit your transaction, you will encounter a java.uti.ConcurrentModificationException.

However, In the web-app world where clients maintain state across requests, there is a far more likely scenario in which your data can get stomped on.  Consider the following scenario involving a bug tracking system:

Time 1: User A brings up the details page for Bug 838.
Time 2: User B brings up the details page for Bug 838.
Time 3: User A assigns Bug 838 to Jim.
Time 4: User B assigns Bug 838 to Sally.

Even though User A and User B updated Bug 838 at different times, User A's update was effectively stomped on by User B. If you're doing something like compensation planning you'd much rather have your users receive an exception when they make an update based on out-of-date information.  Fortunately this is easy to implement using Slim3 Datastore.  Let's use a Person object with a 'salary' property as an example.

public class Person {

    @Attribute(primaryKey = true)
    private Key key;

    private Integer salary;

    @Attribute(version = true)
    private Long version;

    // ...

public void updateSalary(Key key, Long version, int newSalary) {
    Transaction tx = Datastore.beginTransaction();

    try {
        Person p = Datastore.get(tx, Person.class, key, version);

        Datastore.put(tx, p);
    } catch (ConcurrentModificationException e) {
        if (tx.isActive() {

        throw e;

If you declare a version field on your model object, Datastore.get(Class<?> modelClass, Key key, Long version) will compare the argument value with the value of that field in the datastore.  If the version numbers are not equal, you will encounter a java.util.ConcurrentModificationException. The version number will be incremented by Slim3 Datastore when putting your model to the datastore.


Continue to  Relationships.