[英]Invalidating doctrine ORM cache in a rabbitmq-consumer | Symfony2
我在symfony2应用程序中使用oldsound / rabbitmq-bundle实现了rabbitmq-consumer。该应用程序一次消耗10条消息,并使用带有消息数据中给出的过滤器的doctrine-querybuilder从mysql-db收集数据。 Cachingsystem是APC。 考虑这个查询的精简代码
$qb = $this->entityManager
->getRepository('My\Entity')
->createQueryBuilder();
$qb
->select('sum(this) as this, sum(that) as that')
->andWhere('field in (:values)')
->setParameter('values', $filterValues);
$result = $qb
->getQuery()
->setSingleResult();
对于不同的过滤器值,此查询返回相同数据的10倍。 当消费者重新启动并消耗接下来的10条消息时,我再次获得10次不同的结果。 我认为doctrine-cache对此负责,并尝试使缓存无效,如下所示:
$qb = $this->entityManager
->getRepository('My\Entity')
->createQueryBuilder();
$qb
->select('sum(this) as this, sum(that) as that')
->andWhere('field in (:values)')
->setParameter('values', $filterValues);
$result = $qb
->getQuery()
->setResultCacheLifetime(0)
->setSingleResult();
但没有效果。 我可以通过一次只消耗1条消息来解决此问题,但这会使我的应用程序降低到不可接受的程度。
愿有人暗示我朝着正确的方向前进吗?
谢谢,jojo
它归结为我的代码中的错误。 我以某种方式认为消费者在每次消息消失后都会重新安置。 这不是真的! 在我的查询服务中,我将一些查询的结果保存在类属性中。 然后,代码是这样的:
<?php
if (null === $this->queryResult) {
$this->doQuery();
} else {
return $this->queryResult
}
因此,在消耗了第一条消息之后,在消费者重新启动之前,doQuery()从未再次执行过。 我不得不在每次运行后重置类属性,并且明显地为我修复了它。
获得的经验教训:当您使消费者在进程中消耗多条消息时,请记住,消费者和其中使用的所有服务仅初始化一次,并在消费消息中保持其状态。
关心@Francesco Panina指出我的方向正确。 请原谅迟到的回复:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.