我正在尝试为用户创建一个简单的注册。为了使该注册保持一致,我不能允许使用相同的用户名注册两个用户,因为默认查询的最终一致性。我知道即使有相当大的流量发生这种情况的几率几乎是 0,我希望我的实现是可靠的。我已经实现了应该是强一致的祖先查询,但是当我发布我的应用程序并对其进行测试时,如果我的时间正确,我可以让它注册 2 个具有相同用户名的用户。
def user_parent(group = 'default'):
key = ndb.Key('users', group)
return key
class User(ndb.Model):
username = ndb.StringProperty(required = True)
email = ndb.StringProperty(required = True)
password = ndb.StringProperty(required = True)
@classmethod
def register(cls, username, password, email):
return User(parent = user_parent(),
username = username,
password = password,
email = email)
@classmethod
def by_name(cls, name):
return User.query(User.username == name, ancestor = user_parent()).get()
@classmethod
def by_id(cls, uid):
return User.get_by_id(uid, parent = user_parent())
@classmethod
def by_email(cls, email):
logging.error(User.query(User.email == email, ancestor = user_parent()).get())
return User.query(User.email == email, ancestor = user_parent()).get()
@classmethod
def login(cls, user, password):
u = cls.by_name(user)
if u and u.password == password:
return u
我使用 reg_submit 执行 ajax 请求,我对编程很陌生,并且怀疑这是解决它的最佳解决方案,但我的想法是在这里我通过对 User 模型类的调用进行验证。
if reg_submit == 'True':
reg_email = self.request.get('reg_email')
reg_user = self.request.get('reg_user')
reg_password = self.request.get('reg_password')
reg_verify = self.request.get('reg_verify')
valid = True
if not valid_usr(reg_user):
valid = False
self.write('user')
return
if not valid_mail(reg_email):
valid = False
self.write('mail')
return
if User.by_email(reg_email):
valid = False
self.write('mail')
return
if User.by_name(reg_user):
valid = False
self.write('user')
return
if not valid_pass(reg_password):
valid = False
if reg_password != reg_verify:
valid = False
if valid:
t = User.register(reg_user, reg_password, reg_email)
t.put()
self.login(t)
self.redirect('/')
我通过使查询高度一致的理解是,在复制我的数据库的每台机器都将更新之前,所述查询不会执行。
我如何实现强一致的查询,其中两个用户同时注册,使用相同的用户名,其中一个用户将无法这样做。