我有一个长期运行的守护进程(Symfony2的命令)获得工作过的Redis的工作队列,并执行这些作业,并使用ORM写入数据库。
我注意到,当有对工人死亡,是因为到MySQL连接超时当工人怠速等待工作的倾向。
具体而言,我认为这在日志中:MySQL服务器已消失。
反正是有,我可以有学说自动重新连接? 或者是有一些方法可以让我手动捕获该异常并重新学说ORM?
谢谢
我有一个长期运行的守护进程(Symfony2的命令)获得工作过的Redis的工作队列,并执行这些作业,并使用ORM写入数据库。
我注意到,当有对工人死亡,是因为到MySQL连接超时当工人怠速等待工作的倾向。
具体而言,我认为这在日志中:MySQL服务器已消失。
反正是有,我可以有学说自动重新连接? 或者是有一些方法可以让我手动捕获该异常并重新学说ORM?
谢谢
我在我的Symfony2 beanstalkd守护指挥工人使用这样的:
$em = $this->getContainer()->get('doctrine')->getManager();
if ($em->getConnection()->ping() === false) {
$em->getConnection()->close();
$em->getConnection()->connect();
}
看来,只要有被EntityManager学说中遇到的任何错误/异常,关闭连接和EntityManager的是死了。
由于通常都被包裹在一个事务,并执行该交易在$ entityManager->刷新()被调用时,你可以尝试捕捉异常,并尝试重新EXCUTE或放弃。
你不妨检查异常的更具体抓的确切性质的类型,是否PDOException或别的东西。
对于MySQL已经消失的异常,你可以尝试通过重新设置EntityManager的重新连接。
$managerRegistry = $this->getContainer()->get('doctrine');
$em = $managerRegistry->getEntityManager();
$managerRegistry->resetEntityManager();
这应该使$ EM再使用。 请注意,您将不得不再次重新坚持一切,因为这$ EM是新的。
我有同样的问题与PHP的Gearman工人和学说2。
我想出了一个干净的解决方案是:只要关闭并重新打开在每个作业的连接:
<?php
public function doWork($job){
/* @var $em \Doctrine\ORM\EntityManager */
$em = Zend_Registry::getInstance()->entitymanager;
$em->getConnection()->close();
$em->getConnection()->connect();
}
更新
上述解决方案不符合交易状态应付。 这意味着主义\ DBAL \连接:: close()方法不会重置$ _transactionNestingLevel值,所以如果你不提交事务,这将导致学说同步不可正对与基础DBMS翻译状态。 这可能会导致主义默默忽略开始/提交/回滚的语句,并最终不被提交到数据库管理系统的数据。
换句话说:可以肯定的,如果你用这种方法来提交/回滚事务。
这与此包装它为我工作:
https://github.com/doctrine/dbal/issues/1454
在你的后台程序,你可以添加方法来重新启动每个查询之前,可能的连接。 我正面临使用gaerman工人类似problmes:
我让我的连接数据在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');
}
如果damenon你或许需要静态调用它。