/** * Prepares EntityManager, reset it if closed with error */ protected function ensureEntityManagerReady() { $this->em = $this->registry->getManager(); if (!$this->em->isOpen()) { $this->registry->resetManager(); $this->ensureEntityManagerReady(); } }
/** * Closes the entity manager, and rollbacks the pending transaction on the underlying database connection of a * Doctrine's entity manager with the given name. This method also resets the manager, so as it can be recreated for * a new transaction, when needed. */ protected function rollback() { $this->logger->debug(static::class . '::rollback'); $this->getEntityManager()->rollback(); // Close the manager if there is no transaction started. if (!$this->getEntityManager()->getConnection()->isTransactionActive()) { $this->getEntityManager()->close(); $this->entityManagerRegistry->resetManager(); } }
/** * {@inheritdoc} */ public function write(array $items) { /** @var EntityManager $em */ $em = $this->registry->getManager(); try { $em->beginTransaction(); foreach ($items as $item) { $em->persist($item); } $em->flush(); $em->commit(); $configuration = $this->contextRegistry->getByStepExecution($this->stepExecution)->getConfiguration(); $contextSkipClear = $this->stepExecution->getJobExecution()->getExecutionContext()->get(EntityWriter::SKIP_CLEAR); if (empty($configuration[EntityWriter::SKIP_CLEAR]) && !$contextSkipClear) { $em->clear(); } } catch (\Exception $exception) { $em->rollback(); if (!$em->isOpen()) { $this->registry->resetManager(); } $jobName = $this->stepExecution->getJobExecution()->getJobInstance()->getAlias(); $event = new WriterErrorEvent($items, $jobName, $exception); $this->eventDispatcher->dispatch(WriterErrorEvent::NAME, $event); if ($event->getCouldBeSkipped()) { $importContext = $this->contextRegistry->getByStepExecution($this->stepExecution); $importContext->setValue('error_entries_count', (int) $importContext->getValue('error_entries_count') + count($items)); $this->logger->warning($event->getWarning()); if ($event->getException() === $exception) { // exception are already handled and job can move forward throw new InvalidItemException($event->getWarning(), []); } else { // exception are already created and ready to be rethrown throw $event->getException(); } } else { throw $exception; } } $this->eventDispatcher->dispatch(WriterAfterFlushEvent::NAME, new WriterAfterFlushEvent($em)); }