We have an authentication system which uses Google App Engine as the backend. The underlying languages and frameworks consist of Java, JDO, Google Authentication & Google App Engine.
We have a User Entity. A User Entity is User Meta-data saved from the Google App Engine authentication response (for example: first name, last name, email address).
When a user tries to register or login (both a sign-in event), we scan the datastore to see if a user with the same email address already exists. If the user does not already exist, we create a new user. If the user does exist, we update and retrieve their user information and then retrieve their application data.
We need to run separate, multiple transactions, because the Login page is completely separate of the application page.
In some cases, when a user tries to register twice in a short period of time, a duplicate user is created. While we could always fetch the last user registered, we really want the query to be a unique JDO query. Using a unique JDO query, the JDO query (run inside a transaction) sometimes fails due to two identical values being found (for the user's email address).
We considered the following ways to enforce the constraint:
- storing a freshly registered user's information in cache. We didn't seem to find any information that would suggest cache would be a suitable solution to prevent duplicates. Is cache instantly available across machines? Even if it is, the cache could eject an entity for various reasons.
- storing the user's email in a session. This seemed to bloat the code and seemed a bizarre way to enforce constraints.
Is there a best-practices approach with Google App Engine to prevent duplicate values during an authentication workflow, and separate transactions?