Исключение PessimisticLockException
Исключение PessimisticLockException относится к классам Doctrine ORM
и выбрасывается в момент, когда одна транзакция пытается получить
пессимистичную блокировку строки, уже заблокированной другой транзакцией.
Класс находится в пространстве имён Doctrine\ORM\PessimisticLockException
и наследуется от базового Doctrine\ORM\Exception\PessimisticLockException.
Пессимистичная блокировка устанавливается через метод lock
менеджера сущностей EntityManager. Вторым параметром передаётся
режим блокировки: LockMode::PESSIMISTIC_READ или
LockMode::PESSIMISTIC_WRITE. Если строку уже держит другая
транзакция, выбрасывается данное исключение.
Синтаксис
<?php
use Doctrine\ORM\PessimisticLockException;
throw new PessimisticLockException($message);
?>
Пример
Давайте опишем сущность Article с полем title:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Article
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private string $title = '';
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
}
?>
Пример
Давайте попробуем заблокировать строку, которая уже удерживается другой транзакцией, и перехватим исключение:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\DBAL\LockMode;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\PessimisticLockException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class ArticleController extends AbstractController
{
public function lock(EntityManagerInterface $em): Response
{
try {
$article = $em->find(Article::class, 1);
$em->lock($article, LockMode::PESSIMISTIC_WRITE);
return new Response('locked');
} catch (PessimisticLockException $e) {
return new Response('lock failed: ' . $e->getMessage());
}
}
}
?>
Результат выполнения кода при конфликте блокировок:
"lock failed: The pessimistic lock could not be acquired."
Пример
Давайте завернём работу с блокировкой в транзакцию и обработаем
исключение через метод getMessage:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\DBAL\LockMode;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\PessimisticLockException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class ArticleController extends AbstractController
{
public function update(EntityManagerInterface $em): Response
{
$em->beginTransaction();
try {
$article = $em->find(Article::class, 1);
$em->lock($article, LockMode::PESSIMISTIC_READ);
$article->setTitle('abcde');
$em->flush();
$em->commit();
return new Response('updated');
} catch (PessimisticLockException $e) {
$em->rollback();
return new Response('error: ' . $e->getMessage());
}
}
}
?>
Результат выполнения кода при успешной блокировке:
"updated"
Смотрите также
-
исключение
OptimisticLockException,
которое выбрасывается при оптимистичной блокировке -
исключение
LockedHttpException,
которое возвращает HTTP-код 423 -
исключение
EntityNotFoundException,
которое выбрасывается при отсутствии сущности -
исключение
ORMInvalidArgumentException,
которое выбрасывается при неверных аргументах ORM