У меня есть веб-приложение. Процесс обработки формы в нем выглядит так:
- Validate
- Список ошибок или вставка / обновление данных
В этом конкретном сценарии я разрабатываю процесс регистрации пользователей, но пытаюсь найти общее решение для всех типов форм на основе проверки наличия уникального значения в таблице базы данных.
В этой регистрации пользователя логин пользователя должен быть уникальным. На этапе проверки приложение проверяет его наличие в таблице базы данных и, если оно доступно, вставляет строку. Есть и другие поля, которые должны быть проверены, такие как пароль и подтверждение пароля Вся проверка происходит один раз в одном HTTP-запросе.
Проблема в том, что я не могу быть уверен, что после приложение проверило его доступность, оно не было принято другим пользователем в параллельном процессе до процесса первого пользователь вставляет его. Я понимаю, что существует очень и очень небольшая вероятность того, что два пользователя введут один и тот же логин в одну и ту же миллисекунду, но когда-нибудь это может произойти с другой формой, когда несколько тысяч пользователей вводят данные в какую-либо форму одновременно.
Если проверка уже пройдена, пользователь не должен видеть сообщение об ошибке, в котором говорится, что его логин уже зарегистрирован.
Что я пытаюсь решить, так это убедиться, что уникальное значение доступно после проверки его доступности и перед вставкой его в один HTTP-запрос. Это нормально, что другой пользователь зарегистрировал тот же уникальный логин, в то время как первый перебирал свой пароль и пароль не совпадает.
Эта проблема легко решается с помощью существующей строки, поскольку я могу выбрать ее для обновления, и она будет заблокирована во время транзакции. Но я не могу сделать то же самое с несуществующей строкой. Это проблема. Как мне это решить?
Вот некоторые известные мне решения. Я не уверен, какой из них лучший. Более того, я не уверен, что мне известен лучший способ, поэтому, пожалуйста, поделитесь известными вам способами.
Стол блокировочный
Я уже решил эту проблему в прошлом с помощью блокировки таблицы, но я не уверен, что это был лучший способ сделать это. Процесс пошел так:
- Блокировка таблицы для записи
- Проверить наличие мест
- Вернуть ошибку или вставить строку
- Разблокировать стол
Некоторые люди говорят, что блокировка всей таблицы - худшее решение из всех. Может быть, это так, но это единственный способ, который я мог придумать сам, который работал.
Блокировка остается только во время одного HTTP-запроса и, конечно, не между несколькими из них.
Вставить и поймать ошибку
Так мне предложили другие ребята. Они предложили сделать этот столбец уникальным индексным столбцом и раздельно проверять и проверять уникальность в два этапа. Процесс идет так:
- Проверка данных
- Если проверка прошла успешно, вставьте строку
- Если при вставке строки произошла ошибка, отобразится ошибка недоступности уникального значения
Конечно, я сделал столбец уникальным индексным столбцом. Но это не значит, что я хочу использовать возможности базы данных, чтобы выдать ошибку при проверке; это должно быть сделано на уровне приложения.
Мне не нравится этот способ, потому что мне не нравится способ «попробуй и поймай исключение» в этом сценарии, потому что нет ничего исключительного в процессе проверки доступности значения и его вставки. Я полагаю, что это должно быть способом проверки и резервирования и вставки. Я считаю, что проверка ввода пользователя не должна основываться на исключениях, потому что нет ничего исключительного в том, что пользователь вводит что-то неправильное.
Я могу ошибаться, но это моя текущая точка зрения. Если вы думаете, что я явно ошибаюсь, скажите, пожалуйста, почему.