google-app-engine
Appengine ndb - Transactions can report failure but succeed
I have some concerns over using Appengine after finding this: https://cloud.google.com/appengine/docs/python/datastore/transactions 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. Ndb transactions: https://cloud.google.com/appengine/docs/python/ndb/transactions This post has touched on the subject before but not answered it: app engine datastore transaction exception I have searched and read about the issue but cannot find anything more specific. I have a game where I will do the following: signup login update progress update password/email delete account 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. If we start with what I have, I see some problems. I need to understand exactly how things work. 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? 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. 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. And when are the exceptions like TransactionFailedError returned? After each try or only after all retries failed? 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.
Related Links
GQL Random Record [duplicate]
AppEngine entity modeling - minimizing entity groups and achieving atomic cascading update/delete
What does _ah mean in Google App Engine?
Spring Roo with GAE error on most basic tests
Running a web crawler for selected sites on google app engine?
Many-to-many relationship modeling in google app engine
Appengine: ClassCastException in query with string of leng
How to integrate user quotas?
Restlet that works on localhost throws NullPointerException when deployed on GAE
No module named Crypto.Cipher on local mac AppEngine
Should I use a GZIP compression middleware or not?
AppEngine vs. sendmail space problem
nosetests 'cannot import name mkdir'
What is the benefit / usage of a AppEngine remote procedure call
How use AppEngine's Datastore Admin: Copy to Another App Feature
Balancing server/client load for autocompletion search