Как предотвратить повторные запросы от одного пользователя
На сайте пользователям раз в сутки доступен 1 подарок. Интерфейс сайта не позволяет получить более одного подарка в сутки. Так же перед зачислением подарка пользователю идет проверка на возможность его получения путем проверки записей в БД о полученных ранее гифтов в течении суток. Если же отправить сразу два запроса, например через консоль браузера, то сервер на оба запроса отвечает положительно. Видимо после первого запроса запись не успевает добавиться в БД и сервер считает, что ранее пользователь не получал подарки в текущих сутках. Вопрос в том, как запретить повторное получение подарка в течении одних суток. БД mariaDB. Запросы обрабатываются через nginx, php.
Ответы (2 шт):
Делаем таблицу
CREATE TABLE gifts ( giftdatetime DATETIME DEFAULT CURRENT_TIMESTAMP,
giftdate DATE AS (DATE(giftdatetime)),
userid BIGINT,
UNIQUE (giftdate, userid) );
и просто вставляем в неё идентификатор пользователя:
INSERT INTO gifts (userid) VALUES ({идентификатор пользователя});
Если пользователь сегодня уже участвовал в процессе - возникнет ошибка дублирования уникального ключа, которая легко ловится на клиенте. И никакие "Если же отправить сразу два запроса" это не объедут.
Предложенный @Akina вариант валидный, но предложу другой вариант. Генерируйте key для каждого пользователя так, чтоб при множественной попытке вставки результат был всегда одним.
@giftKey = day(serverTime вы можете ключ на сервере) + "_{giftType}" + "_" +"{userId}"
CREATE TABLE gifts ( giftdatetime DATETIME DEFAULT CURRENT_TIMESTAMP,
giftKey TEXT, (тут не принципиально)
userid BIGINT,
UNIQUE (giftKey) );
INSERT INTO gifts (@giftKey, @userid) VALUES ({идентификатор пользователя});
В чем принципиальная разница? В случае если вам действительно нужно будет дать приз в этот же день по другой любой причине вы спокойно это сделаете указав причину либо вовсе добавив GUID к ключу если это приз вручаемый несколько раз .... А сделать по той же причине с тем же ключом не удаться.