ユーザー用の簡単な登録簿を作成しようとしています。その登録の一貫性を保つために、デフォルト クエリの最終的な一貫性を考慮して、同じユーザー名で 2 人のユーザーを登録することはできません。かなりのトラフィックがあっても、その可能性はほぼ 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('/')
クエリを強力に一貫性のあるものにすることで理解していることは、データベースが複製されているすべてのマシンが更新されるまで、上記のクエリは実行されないということです。
2 人のユーザーが同時に登録し、同じユーザー名を使用して、そのうちの 1 人が登録できない場合に、強力に一貫性のあるクエリを実行するにはどうすればよいですか。