Properly handling transaction rollbacks using the Google App Engine

I am not sure if I understand the Google documentation, I wonder if anyone else can check my understanding.

Is the following code guaranteed to only do the following two things:

  • bank account balance update
  • save transaction record.

Below I understand correctly:

public void add(String account, Double value, String description, Date date) throws EntityNotFoundException {
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    int retries = 3;
    while (true) {
        Transaction txn = datastore.beginTransaction();
        try {

            // Update the bank balance
            Key key = KeyFactory.createKey("Account", account);
            Entity e = datastore.get(key);
            Double balance = (Double) e.getProperty("balance");
            balance += value;
            e.setProperty("balance", value);
            datastore.put(e);

            // Record transaction details
            Entity d = new Entity("Transaction", key);
            d.setProperty("account_key", key);
            d.setProperty("date", date);
            d.setProperty("value", value);
            d.setProperty("description", description);

            txn.commit();
            break;
        } catch (ConcurrentModificationException e) {
            if (retries == 0) throw e;
            retries--;
        } finally {
            if (txn.isActive()) txn.rollback();
        }
    }
    }
}
+3
source share
2 answers

It is right. There is no need to include the key in the account in the entity, however - the entity you create is a child of the account in question.

+2
source

ConcurrentModificationException , . http://code.google.com/appengine/docs/java/datastore/transactions.html, : " , . DatastoreTimeoutException, ConcurrentModificationException DatastoreFailureException , . Datastore , , , ." ConcurrentModificationException, , - , , , .

0

All Articles