Метод wrapInTransaction
Метод wrapInTransaction класса EntityManager
выполняет переданную функцию внутри транзакции.
Первым параметром передаётся вызываемая функция,
внутри которой выполняются операции с сущностями.
Если функция завершается без исключений, транзакция
автоматически фиксируется. Если возникает исключение,
транзакция откатывается, а исключение пробрасывается дальше.
Метод возвращает результат выполнения переданной функции.
Это удобная альтернатива ручному управлению транзакциями
через методы beginTransaction, commit
и rollback.
Синтаксис
public function wrapInTransaction(callable $func): mixed
Пример
Давайте создадим сущность и сохраним её внутри транзакции:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/article', name: 'article_create')]
public function create(EntityManagerInterface $em): Response
{
$res = $em->wrapInTransaction(function () use ($em) {
$article = new Article();
$article->setTitle('article');
$article->setText('abcde');
$em->persist($article);
return $article->getTitle();
});
return new Response($res);
}
}
?>
Результат выполнения кода:
article
Пример
Давайте посмотрим, как метод обрабатывает исключение и откатывает транзакцию:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/article/safe', name: 'article_safe')]
public function safe(EntityManagerInterface $em): Response
{
try {
$em->wrapInTransaction(function () use ($em) {
$article = new Article();
$article->setTitle('article');
$article->setText('abcde');
$em->persist($article);
throw new \Exception('rollback');
});
} catch (\Exception $e) {
return new Response($e->getMessage());
}
return new Response('hello');
}
}
?>
Результат выполнения кода:
rollback
В данном примере запись в базу данных не произошла, так как транзакция была откачена.
Пример
Давайте вернём массив результатов из транзакции:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/articles', name: 'article_list')]
public function list(EntityManagerInterface $em): JsonResponse
{
$res = $em->wrapInTransaction(function () use ($em) {
$titles = [];
foreach (['abcde', 'article', 'user'] as $title) {
$article = new Article();
$article->setTitle($title);
$article->setText('hello');
$em->persist($article);
$titles[] = $title;
}
return $titles;
});
return new JsonResponse($res);
}
}
?>
Результат выполнения кода:
["abcde", "article", "user"]
Смотрите также
-
класс
EntityManager,
который управляет сущностями и транзакциями -
метод
beginTransaction,
который вручную начинает транзакцию -
метод
commit,
который фиксирует текущую транзакцию -
метод
rollback,
который откатывает текущую транзакцию