title: Appengine ndb - Transactions can report failure but succeed
body: <p>I have some concerns over using Appengine after finding this:
  <a href="https://cloud.google.com/appengine/docs/python/datastore/transactions" rel="nofollow noreferrer">https://cloud.google.com/appengine/docs/python/datastore/transactions</a></p>
  
  <blockquote>
    <p>Note: If your application receives an exception when committing a
    transaction, it does not always mean that the transaction failed. You
    can receive Timeout, TransactionFailedError, or InternalError
    exceptions in cases where transactions have been committed and
    eventually will be applied successfully. Whenever possible, make your
    Cloud Datastore transactions idempotent so that if you repeat a
    transaction, the end result will be the same.</p>
  </blockquote>
  
  <p>Ndb transactions:
  <a href="https://cloud.google.com/appengine/docs/python/ndb/transactions" rel="nofollow noreferrer">https://cloud.google.com/appengine/docs/python/ndb/transactions</a></p>
  
  <p>This post has touched on the subject before but not answered it:
  <a href="https://stackoverflow.com/questions/13740724/app-engine-datastore-transaction-exception">app engine datastore transaction exception</a></p>
  
  <p>I have searched and read about the issue but cannot find anything more specific.
  I have a game where I will do the following:</p>
  
  <ul>
  <li>signup</li>
  <li>login</li>
  <li>update progress</li>
  <li>update password/email</li>
  <li>delete account</li>
  </ul>
  
  <p>As it is only one entity is modified at a time (updating progress or pw etc). In the future I might add multiplayer which might complicate things since it could mean updates to more than one entity at a time.</p>
  
  <p>If we start with what I have, I see some problems. I need to understand exactly how things work. </p>
  
  <ul>
  <li>What does it mean if a failure is reported but it actually succeeds later?
  Let's say the progress has been saved successfully before and is level 12. Now the user posts that he/she progressed to level 15. It reports failure but succeeds later. Let's say the user's brother plays with the same profile on another device which is only on level 12 and has not seen the other update yet, he completes level 13 and saves. Now what can happen?
  The transaction consists of reading the saved level and if it is bigger then write the new one else keep the old.
  But will transaction number 2 view the old value, decide that it should write 13 and then be enqueued after transaction 1 so that transaction 1 eventually completes and writes 15 but transaction 2 then writes 13 because it looked at the old value?
  Or will transaction number one read the value before the actual true write and write 15 and then transaction 2 will also read the true value which is now 15 and then not write 13?
  What does it mean that the transaction has been commited?</li>
  <li>For signup it could mean the signup is reported as a failure but is written to the database and then the user tries to signup again but the server says that the email already exists. This will annoy people.</li>
  <li>Updating emails and passwords - The user updates the pw or email and it is reported to have failed. So they log in with the old pw just to see that it does not work because the new password was actually written although it said failed. This can be solved by the user by using "forgot password" but it is still very annoying.</li>
  </ul>
  
  <p>And when are the exceptions like TransactionFailedError returned? After each try or only after all retries failed?</p>
  
  <p>Is it possible to give some sort of estimations of how likely all this is? I mean if I have 10 people using it I guess it never happens and everything seems to work but then I get a million users and things start to fail everywhere...
  If these problems occur to one out of one million users one time a year then it is not something to worry about but if it happens to every user once a week it is a disaster.</p>