开发者

Google App Engine - Dealing with concurrency issues of storing an object

开发者 https://www.devze.com 2022-12-25 22:50 出处:网络
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

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:

MyUser.get_or_insert(email)

Getting your MyUser by an email is also easy:

MyUser.get_by_key_name(email)

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 TransactionFailedError to find cases when another user "takes" that username during your transaction.

You definitely don't want to use a memcache mutex, since that while loop waiting for the lock to free up can spend a lot of your memcache API call quota.


If you use the JPA impl of datastore, you just have to set the annotation

@Column(unique=true) Field field

This way the db will reject your insert/update.. i guess it's implemented by gdatastore, it's not a big matter for me to give a "technical error" to the user on such a specific case... but anyway you could catch a constraintviolation exception. I guess JDO also have this.

But actually i don't even know if you'r using Python or Java...

In Java as far as i know you can do a select request in a transaction...

About transactions you should also check what is transaction isolation and how it works on GAE...

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号