我想在数据存储区中创建和存储的User
对象有email
和username
。如何确保在创建User
对象时,另一个User
对象不具有相同的email
或相同的username
?
如果我只是查询是否有其他用户已经使用过用户名或电子邮件,那么可能会出现竞争条件。
更新:
我目前正在考虑的解决方案是使用MemCache来实现锁定机制。在尝试将User
对象存储在数据存储区中之前,我会获得2个锁。首先是一个基于email
锁定的锁,然后是另一个基于username
锁定的锁。
由于创建新的User
对象只发生在用户注册时间,并且两个人尝试使用相同的用户名或相同的电子邮件甚至更少,我认为可以采取锁定的性能损失。
我正在考虑使用此处的MemCache锁定代码:http://appengine-cookbook.appspot.com/recipe/mutex-using-memcache-api/
你们有什么想法?
答案 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上的工作原理......