race condition для HTTP запроса

Рейтинг: 0Ответов: 2Опубликовано: 27.03.2023

Я хочу создать функцию, которая проверяет свободен ли ник в базе Mysql и если свободен, функция создает новую запись в БД. Пользователь одновременно отправляет несколько запросов на проверку свободного ника user и записывает этот ник. В этот момент другие одновременные запросы пользователя тоже могут получить такой ответ, хотя по факту, юзер уже занял этот ник.

Как правильно обработать такой кейс, не блокируя запросы других пользователей к этой функции?

Использую в качестве фреймворка Fiber.

Ответы

▲ 0

Попробую описать по шагам, надеюсь реализовать при желании сможете самостоятельно:

  1. Пользователи шлют запрос на создание какого-то ника например ISuper
  2. Проверяете есть ли он в базе если есть и занят сразу отказываете
  3. Если нет добавляете в базу но не отвечаете пользователю а выдаете ему некий ответ (токен) — таким образом ник пока зарезервирован
  4. При следующем обращении пользователь отсылает полученный токен обратно на сервер
  5. Сервер смотрит с каким ником ассоциируется этот токен (который уже в базе)
  6. Если он еще не присвоен никому то присваивается именно этому пользователю
  7. Следующие запросы будут автоматически отклонятся так как ник в базе уже ассоциирован с конкретным токеном пользователя.
▲ 0

Я бы сделал таблицу с никами: ник, статус, дата истечения, идентификатор сессии

Статусы - активен или захвачен. Для статуса активен остальные колонки пустые.

Для статуса захвачен идентификатор сессии указывает, какой именно из гостей попытался захватить идентификатор, дата истечения указывает, когда захват спадёт, если пользователь не зарегистрируется под этим ником

Проверка ников осуществляется по этой таблице:

  1. Если ника в таблице нет, то ник свободен
  2. Если ник в таблице, статус захвачен, и идентификатор сессии совпадает с идентификатором сессии гостя, то ник свободен

В противном случае ник считается занятым.

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

Если гость не зарегается до даты истечения, то строку с ником удалить.