Как предотвратить состояние гонки при создании документа на сервере синтаксического анализа?

Мобильное приложение использует сервер синтаксического анализа в качестве бэкэнда с mongoDB в качестве базы данных.

Для каждого пользователя в коллекции User есть профиль пользователя в коллекции UserProfile. Профиль пользователя имеет поле указателя как ссылку на User, которому принадлежит профиль пользователя.

Проблема в том, что во время регистрации для одного и того же пользователя создается несколько профилей пользователей.

Это потому, что процесс регистрации выглядит так:

  1. Пользователь Клиент: регистрируется
  2. Сервер: создает профиль пользователя в afterSaveUser
  3. Клиент: после регистрации вызывает функцию облачного кода updateProfile для обновления информации в профиле пользователя
  4. Сервер:updateProfile ищет существующий профиль пользователя или создает новый, если его нет.

Это вызывает состояние гонки: сервер создает профиль пользователя на шаге # 2, и в то же время updateProfile создает новый профиль пользователя на шаге # 4. Разница во времени в createdAt этих профилей пользователей составляет миллисекунды.

В настоящее время:

  • Если я пропущу шаг 2, то даже если на шаге 4 вызовы будут выполняться несколько раз сразу после друг друга, это может вызвать состояние гонки, потому что updateProfile не найдет профиль пользователя, пока он не будет создан. С другой стороны, каждый пользователь должен иметь связанный с ним профиль пользователя, поэтому создание его на стороне сервера - единственный способ гарантировать это.

  • Если я изменю шаг № 4, чтобы не создавать новый профиль, то информация в профиле не обновляется, когда клиент вызывает функцию облачного кода updateProfile, потому что профиль пользователя из шага № 1 еще не создан.

Каков правильный подход?

Обновлять:

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

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

Arthur Cinader 16.11.2018 03:27

Я подумал об этом, это предотвращает создание нескольких профилей пользователей. Однако шаг №4 по-прежнему не удастся, потому что он не найдет профиль пользователя, который еще не был создан на этапе №2. Мне нужно что-то, что гарантирует, что операция записи на шаге 2 будет выполнена до операции поиска / изменения на шаге 4.

Manuel 16.11.2018 03:32

так зачем вообще делать №2? почему бы не рассчитывать на № 4, чтобы сделать работу. но вы все равно должны создать уникальный индекс.

Arthur Cinader 16.11.2018 03:37

Пожалуйста, покажите свой код. То, что вы пытаетесь сделать, легко сделать без условий гонки. Вкратце: (а) вы можете настроить хук afterSave для создания профиля и обновить и пропустить шаг 4, или (b) пропустить шаг 2 и после завершения создания пользователя вызвать updateProfile (который сначала выполнит создание, если его нет). Если один или оба этих подхода не работают, код требует проверки.

danh 18.11.2018 00:43

@danh (a) Перехватчик afterSave для класса User не может Обновить профиля пользователя, потому что информация для обновления предоставляется клиентом на шаге 4, поэтому шаг 4 нельзя пропустить. (b) если шаг № 2 пропущен, то создание профиля пользователя определяется клиентом. Если клиент завершает работу после запроса на создание пользователя и до ответа (например, в медленной сети), тогда профиль пользователя не будет создан. Здесь нет кода для проверки, это концептуальный вопрос.

Manuel 18.11.2018 17:51

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

Jake T. 20.11.2018 20:40
Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
0
6
284
0

Другие вопросы по теме