0
votes

I am trying to write two entities in the same entity group, one through objectify, and the other through the low level datastore api. I create a datastore transaction to do this. My code looks like the following -

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Transaction transaction = datastore.beginTransaction();

try {
  Summary summary = Ofy.ofy().load().key(com.googlecode.objectify.Key.create(parent)).now();
  // Change summary
  Ofy.ofy().save().entity(summary).now();
  Key key = KeyFactory.createKey(parent, "Data", id);

  Entity entity = new Entity(key);
  // add stuff to entity
  datastore.put(entity);
  transaction.commit();
} finally {
  if (transaction.isActive()) {
    transaction.rollback();
  }
}

However I recently encountered some data inconsistency which can be explained if this transaction does not guarantee transactional update over both the entities. My question is, is the transaction supposed to work this way?

As per the last FAQ entry here - https://github.com/objectify/objectify/wiki/FrequentlyAskedQuestions, we can mix objectify and datastore writes in a transaction, but the code sample probably uses objectify-transactions. Is that the only way to do it?

1

1 Answers

0
votes

I was able to reproduce the scenario in a test, and indeed we can not do objectify update from datastore-transactions, but we can do datastore-updates from objectify-transactions.

So the following works -

final DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Ofy.ofy().transact(new Work<Void>() {
  @Override
  public Void run() {
    Summary summary = Ofy.ofy().load().key(com.googlecode.objectify.Key.create(parent)).now();
    // Change summary
    Ofy.ofy().save().entity(summary).now();
    Key key = KeyFactory.createKey(parent, "Data", id);

    Entity entity = new Entity(key);
    // add stuff to entity
    datastore.put(entity);
    return null;
  }
});