We are developing an IOS game and are using google-app-engine for backend. The users can cash in in-game money by tapping buildings. The users tap several buildings fairly fast and this causes several concurrent transactions on the same object (USER) and on different buildings.
Unfortunately this means that the 4-5th tap times-out since it looses retries. It also means that 2nd to 5th tap is very slow due to the lock.
My first thought was to make the transaction into a task, but then totalAmount will be wrong on the second call to the function, since the first call is not completed yet.
So any good ways to support multiple fast updates to the same entity?
int retries = 5;
while (retries > 0) {
// Wrap everything into a transaction from here
TransactionOptions options = TransactionOptions.Builder.withXG(true);
Transaction txn = datastore.beginTransaction(options);
try{
// Ok we got the template - now check against the
// Update user... with money gained
// Update Building...money withdrawn
//Do the transaction
datastore.put(txn, user.getEntity());
datastore.put(txn, building.getEntity());
txn.commit();
// do callback code...which returns TotalMoney
break;
} catch (Exception e) {
if(retries > 0){
retries--;
}
else{
//fail code...
} finally {
if (txn.isActive()) {
txn.rollback();
}
}
}
For consistency you need transactions, for responsiveness you shoul use backends:
Use backend instance to keep data in memory for fast update.
Whenever data is updated in backend also start a task and transactionally update entity in Datastore.