守护进程中的Doctrine2连接超时

Jam*_*hen 19 php doctrine symfony doctrine-orm

我有一个长时间运行的守护程序(Symfony2 Command),可以在Redis中的工作队列中工作,并使用orm执行这些作业并写入数据库.

我注意到,当工人怠速等待工作时,工作人员有死亡的倾向,因为与MySQL的连接超时.

具体来说,我在日志中看到了这一点:MySQL Server已经消失了.

无论如何我可以让学说自动重新连接吗?或者有什么方法可以手动捕获异常并重新连接学说orm?

谢谢

小智 25

我在我的symfony2 beanstalkd守护程序命令worker中使用它:

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

  • 快速通知 - 在 2.5 及更高版本中添加了 ping (2认同)

Jam*_*hen 12

似乎只要EnttrManager在Doctrine中遇到任何错误/异常,连接就会关闭,EntityManager就会死机.

因为通常所有事务都包含在事务中,并且在调用$ entityManager-> flush()时执行事务,所以您可以尝试捕获异常并尝试重新执行或放弃.

您可能希望通过更具体的类型捕获来检查异常的确切性质,无论是PDOException还是其他.

对于MySQL有Gone Away异常,您可以尝试通过重置EntityManager来重新连接.

$managerRegistry = $this->getContainer()->get('doctrine');
$em = $managerRegistry->getEntityManager();
$managerRegistry->resetEntityManager();
Run Code Online (Sandbox Code Playgroud)

这应该使$ em再次可用.请注意,您必须再次重新保留所有内容,因为这个$ em是新的.

  • 在重置之前是否有获得经理的意义(不使用$ em引用本身)? (2认同)

pau*_*ago 8

我对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();
}
Run Code Online (Sandbox Code Playgroud)

更新

上述解决方案无法应对交易状态.这意味着Doctrine\DBAL\Connection :: close()方法不会重置$ _transactionNestingLevel值,因此如果您不提交事务,那么将导致Doctrine与底层DBMS的转换状态不同步.这可能导致Doctrine默默地忽略begin/commit/rollback语句,并最终导致数据未提交给DBMS.

换句话说:如果使用此方法,请确保提交/回滚事务.


bla*_*ise 5

这个包装器对我有用:

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

  • 我已经提出它来呈现Doctrine版本,并在此发布了它与Zend Framework的使用https://circlical.squarespace.com/blog/2013/9/12/mysql-server-has-gone-away-atop- doctrine2 - 和 - 的Zend框架-2- (2认同)