Google App Engine - 处理存储对象的并发问题

时间:2010-04-08 20:58:39

标签: google-app-engine concurrency google-cloud-datastore

我想在数据存储区中创建和存储的User对象有emailusername。如何确保在创建User对象时,另一个User对象不具有相同的email或相同的username

如果我只是查询是否有其他用户已经使用过用户名或电子邮件,那么可能会出现竞争条件。

更新: 我目前正在考虑的解决方案是使用MemCache来实现锁定机制。在尝试将User对象存储在数据存储区中之前,我会获得2个锁。首先是一个基于email锁定的锁,然后是另一个基于username锁定的锁。

由于创建新的User对象只发生在用户注册时间,并且两个人尝试使用相同的用户名或相同的电子邮件甚至更少,我认为可以采取锁定的性能损失。

我正在考虑使用此处的MemCache锁定代码:http://appengine-cookbook.appspot.com/recipe/mutex-using-memcache-api/

你们有什么想法?

2 个答案:

答案 0 :(得分:2)

尝试将用户的电子邮件存储为key_name。这可以通过一个简单的步骤完成:

MyUser.get_or_insert(email)

通过电子邮件获取MyUser也很简单:

MyUser.get_by_key_name(email)

请参阅此类似问题:add properties to users google app engine

这解决了两个用户使用相同电子邮件的问题。要对用户名执行相同操作,请执行“使用此用户名获取用户”查询以及“{3}}中的”使用此用户名插入用户“(这是get_or_insert()在幕后执行的操作)。< / p>

如果其他用户在您的交易过程中“获取”该用户名,您可以抓住TransactionFailedError查找案例。

肯定不想使用memcache互斥锁,因为等待锁定释放的while循环可能会花费大量的memcache API调用配额。

答案 1 :(得分:1)

如果您使用数据存储的JPA impl,则只需设置注释

@Column(唯一=真) 场地

这样db就会拒绝你的插入/更新..我猜它是由gdatastore实现的,对于我来说,在这样一个特定情况下给用户提出“技术错误”并不是一件大事......但无论如何你可以捕获约束违规例外。我想JDO也有这个。

但实际上我甚至不知道你是否使用Python或Java ...

据我所知,在Java中你可以在事务中做一个select请求......

关于交易,您还应该检查什么是交易隔离以及它在GAE上的工作原理......