我在 symfony2 应用程序中使用 oldsound/rabbitmq-bundle 实现了一个 rabbitmq-consumer 该应用程序一次使用 10 条消息,并使用 doctrine-querybuilder 和消息数据中给出的过滤器从 mysql-db 收集数据。 缓存系统是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 条消息来解决此问题,但这会使我的应用程序变慢到无法接受的程度。
有人可以在正确的方向上提示我吗?
谢谢, 乔乔
最佳答案
它归结为我的代码中的一个错误。 我以某种方式认为消费者在每条消息被消费后都会重新实例化。这不是真的!在我的查询服务中,我将一些查询的结果保存在类属性中。然后,代码是这样的:
<?php
if (null === $this->queryResult) {
$this->doQuery();
} else {
return $this->queryResult
}
因此,在消费第一条消息后,直到消费者重新启动后,doQuery() 才会再次执行。显然,我必须在每次运行后重置类属性,这对我来说是固定的。
经验教训:当您让消费者在一个流程中消费多个消息时,请记住,消费者和其中使用的所有服务仅初始化一次,并在消费的消息中保持其状态。
感谢@Francesco Panina 为我指明了正确的方向。请原谅迟到的回复:)
关于php - 使 rabbitmq-consumer 中的学说 ORM 缓存失效 |交响乐2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30391860/