Google App Engine - решение проблем одновременного хранения объекта - PullRequest
2 голосов
/ 09 апреля 2010

Мой User объект, который я хочу создать и сохранить в хранилище данных, имеет email и username. Как убедиться, что при создании моего объекта User, что другой объект User также не имеет ни того же самого email, ни того же самого username?

Если я просто сделаю запрос, чтобы посмотреть, не использовали ли другие пользователи имя пользователя или адрес электронной почты, тогда может возникнуть условие гонки.

UPDATE: Решение, которое я сейчас рассматриваю, заключается в использовании MemCache для реализации механизма блокировки. Я бы получил 2 блокировки, прежде чем пытаться сохранить объект User в хранилище данных. Сначала блокировка, основанная на email, затем другая блокировка, основанная на username.

Поскольку создание новых User объектов происходит только во время регистрации пользователя, и еще реже, когда два человека пытаются использовать либо одно и то же имя пользователя или одно и то же электронное письмо, я думаю, что это нормально, чтобы снизить производительность блокировки.

Я подумываю использовать код блокировки MemCache, который здесь: http://appengine -cookbook.appspot.com / recipe / mutex-using-memcache-api /

Что вы, ребята, думаете?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2010

Попробуйте сохранить вашего пользователя с адресом электронной почты как key_name. Это можно сделать одним простым шагом:

MyUser.get_or_insert(email)

Получение вашего MyUser по электронной почте также просто:

MyUser.get_by_key_name(email)

См. Аналогичный вопрос: добавить свойства пользователям google app engine

Так что это решает проблему двух пользователей с одним и тем же адресом электронной почты. Чтобы сделать то же самое для имен пользователей, выполните запрос «получить пользователей с этим именем пользователя» и «вставить пользователя с этим именем пользователя» в транзакцию (это то, что get_or_insert() делает за кадром). 1016 *

Вы можете поймать TransactionFailedError, чтобы найти случаи, когда другой пользователь "берет" это имя пользователя во время вашей транзакции.

Вы определенно не хотите использовать мьютекс memcache, поскольку этот цикл while, ожидающий освобождения блокировки, может потратить большую часть вашей квоты вызовов API memcache.

1 голос
/ 14 апреля 2010

Если вы используете JPA-значение хранилища данных, вам просто нужно установить аннотацию

@ Column (уникальный = истина) Поле

Таким образом, БД отклонит вашу вставку / обновление. Я думаю, что это реализовано gdatastore, для меня не имеет большого значения выдавать «техническую ошибку» пользователю в таком конкретном случае ... но в любом случае вы может поймать исключение ограничения ограничения. Я думаю, у JDO тоже есть это.

Но на самом деле я даже не знаю, используете ли вы Python или Java ...

На Java, насколько я знаю, вы можете сделать запрос на выборку в транзакции ...

Об операциях также следует проверить, что такое изоляция транзакций и как она работает в GAE ...

...