My User object that I want to create and store in the datastore has an email, and a username. How do I make sure when creating my User object that another User object doesn’t also have either the same email or the same username?
If I just do a query to see if any other users have already used the username or the email, then there could be a race condition.
UPDATE:
The solution I’m currently considering is to use the MemCache to implement a locking mechanism. I would acquire 2 locks before trying to store the User object in the datastore. First a lock that locks based on email, then another that locks based on username.
Since creating new User objects only happens at user registration time, and it’s even rarer that two people try to use either the same username or the same email, I think it’s okay to take the performance hit of locking.
I’m thinking of using the MemCache locking code that is here: http://appengine-cookbook.appspot.com/recipe/mutex-using-memcache-api/
What do you guys think?
Try storing your User with their email as the
key_name. This can be done in one simple step:Getting your
MyUserby an email is also easy:See this similar question: add properties to users google app engine
So that solves the problem of two users with the same email. To do the same for usernames, perform the “get users with this username” query and the “insert a user with this username” in a transaction (this is what
get_or_insert()does behind the scenes).You can catch a
TransactionFailedErrorto find cases when another user “takes” that username during your transaction.You definitely don’t want to use a memcache mutex, since that
whileloop waiting for the lock to free up can spend a lot of your memcache API call quota.