Итак, я работаю над проектом на Java, но на самом деле язык здесь не имеет значения.Сохранение пользователей в хранилище данных с уникальными адресами электронной почты
Так что я хочу создавать и хранить пользователей в хранилище данных, и я пытаюсь разработать наилучший способ сделать это, чтобы я мог гарантировать, что письмо не будет использоваться более одного раза. Таким образом, обычный способ сделать это в реляционной базе данных ACID будет во время транзакции. Заблокируйте базу данных, посмотрите, существует ли электронное письмо, если оно разблокируется и завершается неудачно, иначе вставьте и разблокируйте.
Теперь это как концепция будет работать в Appengine, а также вы можете использовать транзакции. Однако, поскольку запись могла быть вставлена только миллисекундами раньше, она может отсутствовать в хранилище данных из-за сильной/возможной согласованности.
Так что я думал о:
с использованием глобального родителя для всех пользователей, таких, что я могу затем сделать запрос по предку в моей транзакции, тем самым вынуждая его быть последние данные запрошенные. Однако при этом возникают проблемы с лимитом 1 XG-обновления в секунду. (Это подход, к которому я решил не пойти)
хранение электронных писем, которые вставляются в memcache в отдельный список, потому что даже если он должен быть очищен, он, вероятно, не будет очищен до запись вставляется в хранилище данных, поэтому мы могли бы выполнить поиск как в кеше, так и в хранилище данных, а если его нет, мы можем предположить, что он не будет находиться в хранилище данных. Однако, это Memcache поиск не будет частью сделки, так что все равно будет проблемы
Так что мой главный вопрос заключается в том, что ни один из этих подходов будет использовать запрос предка, так не может быть сделан как часть сделка.
Благодаря
Edit: Подумав о структуре, я рассматриваю что-то вроде этого. Мне нужно будет проверить это, когда я вернусь домой позже, и отметьте это как мой принятый ответ, если он сработает.
UserBean
@id Long id;
//All child elements will use UserBean as their parent
Login
@id String id; //This will be the a hashed/base64 version of the email address
@Parent UserBean user;
String emailAddress
String hashedPassword;
start transaction
Login login = ofy()
.load()
.type(Login.class)
.key(hashEmail(emailAddress)).now();
if (login == null) {
fail transaction - email already in use
}
Insert UserBean and Login objects into datastore
Мысль № 1: по той причине, что вы назвали этот было бы плохой идеей. Мысль № 2: Однако маловероятно, что memcache выселяется только в неправильный/правильный момент - если это так, s *** действительно попадает в вентилятор. Поэтому не делайте обычных случаев, когда необычный случай сломает вам шею. Моя мысль: считаете ли вы создание таблицы, в которой письмо является '@ Id'? Если я получаю свои факты прямо, запросы по id всегда сильно согласованы. – konqi
Но они не могут быть выполнены в транзакции, если только у меня не было дочернего объекта, у которого также было письмо, а затем я могу выполнить запрос предка, чтобы проверить, присутствует ли дочерний элемент. Но это вызывает много операций db, если пользователь хочет изменить свой адрес электронной почты, так как это потребует обновления всех дочерних элементов по мере изменения идентификатора родителей, нет? – Branks
Взгляните на http://stackoverflow.com/questions/24085216/appengine-python-how-to-ensure-that-users-register-with-unique-uersnames/24093300#24093300, в этом мы использовали «уникальные» имена пользователей , но подход применим для электронной почты. –