Задать вопрос
@Romo4ka_eto_ia
Просто человек

Как избавиться от одновременных запросов в PHP?

Здравствуйте. Писал сайт и возникла интересная проблема. Я случайно одновременно отправил 2 одинаковых fetch на PHP сервер, которые должны завершать услугу и возвращать деньги на баланс, и они 2 раза завершили одну услугу и 2 раза вернули деньги. Как я понимаю, всё это произошло из-за того, что между получением данных из базы и их валидацией прошло какое то время, и оба запроса получили данные о том что услуга не завершена.

Я довольно долго думал, что можно сделать, но так ни к чему и не пришел.
Как можно исправить данную проблему?

UPD: Решил проблему вот так:
UPDATE `table` SET `status` = 'CANCEL' WHERE `id` = '{$this->id}' AND NOT (SELECT `status` FROM `table` WHERE `id` = '{$this->id}') = 'CANCEL';
  • Вопрос задан
  • 327 просмотров
Подписаться 1 Средний 9 комментариев
Решения вопроса 1
Adamos
@Adamos
Стоит попытаться сделать операцию атомарной, одним запросом.
Например, вместо SELECT ... if ... UPDATE
выполнять
UPDATE ... if( affected_rows > 0) ...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
SilenceOfWinter
@SilenceOfWinter Куратор тега PHP
та еще зажигалка...
как вариант, блокировать post запросы отправляемые чаще 1сек. на уровне http сервера, блокировать submit перед отправкой данных в js или создавать cookie co сроком жизни 1 сек. и проверять перед отправкой sql запроса в PHP
Ответ написан
@rPman
'запросы в базу данных' в принципе не должны позволять делать двойную трату, причем все финансовые транзакции должны подразумевать что их могут дублировать, подделывать, отменять в процессе выполнения, включая проблемы с железом (например переполненный диск) правильное тестирование финансового сервиса должно пережить не только издевательство клиентов, но и проблемы с самим сервером.

на любой чих нужны проверки статусов, а не делаете ли вы сейчас эту же операцию (уже ответили, в условие обновления ставишь проверку статуса, и все параллельные запросы отвалятся на этом моменте)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы