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)
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是新的.
我对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.
换句话说:如果使用此方法,请确保提交/回滚事务.
这个包装器对我有用:
https://github.com/doctrine/dbal/issues/1454
| 归档时间: |
|
| 查看次数: |
16406 次 |
| 最近记录: |