Intereting Posts
Ошибка PHP: «Не удается передать параметр 2 по ссылке» Zend Application из подкаталога, в котором правильны ссылки на Zend MCRYPT_DEV_RANDOM замерзает, но MCRYPT_DEV_URANDOM работает PHP: проверьте, является ли объект / массив ссылкой PHP-массив Кодирование и декодирование: нужна функция для кодирования и декодирования строки или массива с разделителями или массивом Каков наилучший способ использования API Twitter через PHP? Новый API Instagram – как вы запрашиваете тегированные носители? Скопируйте большие файлы (более 2 ГБ) в PHP Интерфейс или абстрактный класс: какой из них использовать? Как установить переменную $ _GET Как создавать объекты в PHP Хотите использовать методы GET и POST Пользовательская клавиатура Telegram Bot на PHP Продолжайте получать «Ежедневный лимит неисполненного использования превышен. Продолжение использования требует регистрации "при попытке Google плюс вход в мое веб-приложение Как заставить .htaccess использовать для маршрутизации, чтобы не маршрутизировать файлы .css, .js, .jpg и т. Д.?

Тайм-аут соединения Doctrine2 в демонах

У меня есть длинный демон (Symfony2 Command), который получает работу из рабочей очереди в Redis и выполняет эти задания и записывает в базу данных с помощью orm.

Я заметил, что когда есть тенденция к тому, что работник умрет, потому что связь с MySQL приурочена, когда рабочий работает на холостом ходу, ожидая работы.

В частности, я вижу это в журнале: MySQL Server ушел.

Есть ли в любом случае, что учение может автоматически подключаться? Или есть способ, которым я могу вручную поймать исключение и снова подключить доктрину orm?

благодаря

Solutions Collecting From Web of "Тайм-аут соединения Doctrine2 в демонах"

Я использую это в моем Symfony2 beanstalkd daemon Командный рабочий:

$em = $this->getContainer()->get('doctrine')->getManager(); if ($em->getConnection()->ping() === false) { $em->getConnection()->close(); $em->getConnection()->connect(); } 

Похоже, что всякий раз, когда в Doctrine возникает ошибка / исключение, встречающееся в EntityManager, соединение закрывается и EntityManager мертв.

Поскольку, как правило, все заключено в транзакцию и транзакция выполняется, когда вызывается $ entityManager-> flush (), вы можете попытаться поймать исключение и попытаться повторно удалить или отказаться.

Вы можете изучить точный характер исключения с более конкретным уловом типа, будь то PDOException или что-то еще.

Для исключения MySQL Gone Away вы можете попытаться восстановить соединение, сбросив EntityManager.

 $managerRegistry = $this->getContainer()->get('doctrine'); $em = $managerRegistry->getEntityManager(); $managerRegistry->resetEntityManager(); 

Это должно снова использовать $ em. Обратите внимание, что вам придется повторно сохранить все снова, так как это $ em является новым.

У меня была такая же проблема с работником PHP Gearman и Doctrine 2.

Самое чистое решение, с которым я столкнулся, – это просто закрыть и снова открыть соединение на каждой задаче:

 <?php public function doWork($job){ /* @var $em \Doctrine\ORM\EntityManager */ $em = Zend_Registry::getInstance()->entitymanager; $em->getConnection()->close(); $em->getConnection()->connect(); } 

Обновить

Вышеприведенное решение не справляется со статусом транзакции. Это означает, что метод Doctrine \ DBAL \ Connection :: close () не сбрасывает значение $ _transactionNestingLevel, поэтому, если вы не совершаете транзакцию, это приведет к тому, что Doctrine не будет синхронизироваться с статусом трансляции с базовыми СУБД , Это может привести к тому, что Doctrine молча игнорирует операторы start / commit / rollback и, в конечном итоге, данные, которые не передаются в СУБД.

Другими словами: не забудьте совершить транзакции / откат, если вы используете этот метод.

Это с этой оберткой это сработало для меня:

https://github.com/doctrine/dbal/issues/1454

В вашем демоне вы можете добавить метод перезапуска соединения, возможно, перед каждым запросом. Я столкнулся с подобными проблемами с использованием рабочего gaerman:

Я сохраняю данные подключения в zend-реестре, поэтому он выглядит так:

 private function resetDoctrineConnection() { $doctrineManager = Doctrine_Manager::getInstance(); $doctrineManager->reset(); $dsn = Zend_Registry::get('dsn'); $manager = Doctrine_Manager::getInstance(); $manager->setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, true); Doctrine_Manager::connection($dsn, 'doctrine'); } 

Если это проклятие, вам нужно, возможно, назвать его статически.