Given a simple Objectify v5 entity like
@Entity
@Cache
public class Thing {
@Id
public String uid;
public int a;
public int b;
}
What is the correct way of updating existing entities when I want the following to be true
- 0 database operations when the update changes nothing. I.e. the cache should be used and not invalidated when there is no property change.
- consistency: independent, concurrent updates of properties
aandbmust not revert changes of the other property back => transaction
Without detection of changes, the following should work
public static Thing updateA( final String uid, final int value ) {
return ofy().transact(new Work<Thing>() {
@Override
public Thing run() {
Thing thing = ofy().load().type(Thing.class).id(uid).safe();
thing.a = value;
ofy().save().entity(thing);
return thing;
}
});
}
However, since Objectify - to my knowledge - does not detect changes, above code would actually overwrite the entity, flush the cache, etc. Exactly what I try to prevent.
If saving is made conditional like
if (thing.a != value) {
thing.a = value;
ofy().save().entity(thing);
} else {
// consistency guarantees w/o save?
// need to transaction rollback / commit?
}
would that work as desired? In other words, what happens with a transaction that just loads a value but never saves one? My understanding of optimistic locking is that some action at the end of an transaction needs to verify that the state is as desired. That feels like it's missing when not saving.