Таблица блокировок Symfony4 / 5 для критических транзакций doctrine - PullRequest
0 голосов
/ 29 января 2020

У меня относительно критический сценарий для действия контроллера.

Он создает новую сущность и устанавливает ранг, если ни один не определен. Для этой логики c я считаю все связанные сущности, которые были созданы в то время, а затем я считаю наибольшее число плюс один. Вот и все.

Но поскольку я отправляю 10 запросов одновременно, есть дубликаты, которые я хочу предотвратить.

Но блокировка, похоже, не работает.

enter image description here

И это действие контроллера:

public function addPolygonToRoute(Request $request, RoutePolygonRepository $routePolygonRepository, Route $entity)
{
    $this->denyAccessUnlessGranted(RouteVoter::EDIT, $entity);

    /** @var \Doctrine\DBAL\Connection $conn */
    $conn = $this->getDoctrine()->getConnection();
    $conn->beginTransaction();

    $routePolygon = new RoutePolygon();
    $routePolygon->setRoute($entity);

    $form = $this->createForm(RoutePolygonType::class, $routePolygon);
    $form->submit($request->request->all(), true);

    if ($form->isSubmitted() && $form->isValid())
    {
        if ($foundRoutePolygon = $routePolygonRepository->findOneBy([
            'polygon' => $routePolygon->getPolygon(),
            'route' => $routePolygon->getRoute()
        ])) {
            if (null !== $routePolygon->getRank())
            {
                $foundRoutePolygon->setRank($routePolygon->getRank());
            }
            $routePolygon = $foundRoutePolygon;
        }

        if(null === $routePolygon->getRank())
        {
            $routePolygon->setRank(max($entity->getRoutePolygons()->map(function(RoutePolygon $routePolygon) {
                    return $routePolygon->getRank();
                })->toArray() + [0]) + 1);
        }

        $em = $this->getDoctrine()->getManager();
        $em->persist($routePolygon);
        $em->flush();

        $conn->commit();
        return $routePolygon;
    }

    $conn->commit();

    return $this->view($this->getErrorsView($form->getErrors(true, true)), Response::HTTP_BAD_REQUEST);
}

В зависимости от запросов это иногда работает, но когда Symfony обрабатывает 2 запроса одновременно, подсчет не работает.

1 -> 2 2 2 -> 3 -> 4 -> 5 5
...