* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Bridge\Doctrine\Messenger; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\ManagerRegistry; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Middleware\StackInterface; /** * Middleware to log when transaction has been left open. * * @author Grégoire Pineau */ class DoctrineOpenTransactionLoggerMiddleware extends AbstractDoctrineMiddleware { private bool $isHandling = false; public function __construct( ManagerRegistry $managerRegistry, ?string $entityManagerName = null, private readonly ?LoggerInterface $logger = null, ) { parent::__construct($managerRegistry, $entityManagerName); } protected function handleForManager(EntityManagerInterface $entityManager, Envelope $envelope, StackInterface $stack): Envelope { if ($this->isHandling) { return $stack->next()->handle($envelope, $stack); } $this->isHandling = true; $initialTransactionLevel = $entityManager->getConnection()->getTransactionNestingLevel(); try { return $stack->next()->handle($envelope, $stack); } finally { if ($entityManager->getConnection()->getTransactionNestingLevel() > $initialTransactionLevel) { $this->logger?->error('A handler opened a transaction but did not close it.', [ 'message' => $envelope->getMessage(), ]); } $this->isHandling = false; } } }