Reputation: 20136
I am not sure if I am understanding the google documentation, I am wondering if someone else can check my understanding.
Is the following code guaranteed to only ever do both of the following:
Below is what I understand is correct:
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();
}
}
}
}
Upvotes: 3
Views: 286
Reputation: 803
Not necessarily a ConcurrentModificationException indicates that a transaction failed. It's an absolute ambiguity in the documentation http://code.google.com/appengine/docs/java/datastore/transactions.html where it says "If your app receives an exception when submitting a transaction, it does not always mean that the transaction failed. You can receive DatastoreTimeoutException, ConcurrentModificationException, or DatastoreFailureException exceptions in cases where transactions have been committed and eventually will be applied successfully. Whenever possible, make your Datastore transactions idempotent so that if you repeat a transaction, the end result will be the same." I've created a separate topic for this issue here Transactions and ConcurrentModificationException documentation ambiguity so if anyone understands how it really should be dealt with, please update there as well.
Upvotes: 0
Reputation: 101149
That's correct. It's not necessary to include the key of the account in the entity, though - the entity you're creating is a child of the account in question.
Upvotes: 2