Symfony / Doctrine параллельная атака HTTP-запросов - PullRequest
0 голосов
/ 05 июня 2019

Когда два или более HTTP-запроса выполняются одновременно (например, с curl_multi_exec) к заданной конечной точке с использованием одного и того же идентификатора сеанса. Объекты Symfony / Doctrine загружаются с «текущими» данными базы данных.

Представьте себе следующий сценарий:

  1. пользовательских хитов / трансфер / usd? Сумма = 10
  2. внутри контроллера есть:
$withdrawAmount = $request->get('amount');

if($currentUser->getBalance() >= $withdrawAmount)
{
    //sure - you can transfer your money somewhere...
    $currentUser->setBalance($currentUser->getBalance() - withdrawAmount);
    $em->persist($currentUser);
    $em->flush();

    //send money somewhere
    ...

    //do something time consuming, etc
    ...
}

Теперь в контексте параллельного запроса два или более запроса, попадающих в одну и ту же конечную точку, фактически будут проходить проверку getBalance (), поскольку она будет считывать «текущий» баланс, что приводит к нескольким передачам, когда это вообще не должно быть возможным. Запись в базе данных будет обновляться несколько раз, но последний запрос будет содержать последнее слово, и если его сумма равна 0,01, это все, что будет выведено из текущего баланса пользователя.

Использование очереди с cronjob решит вышеупомянутую проблему, но все же элементы очереди будут вставлены по той же причине - проверка «провал» в контроллере.

Это всего лишь воображаемый сценарий, но действительный - это происходит по-настоящему.

Как можно преодолеть это? (Я даже не уверен, как назвать эту «проблему»)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...