Doctrine2缓存腐败?

时间:2012-09-12 19:56:27

标签: php symfony doctrine-orm memcached

我有一个像Bellow一样的存储库。

代码首先检查项目是否已在表格中。

  • 如果不是,则下载数据然后将其存储到表中。

  • 如果它已经在表格中,则只返回记录。

但有时在它检查表中的项目之后它仍会继续尝试下载并存储该项目,即使它已经存在,也会产生关键冲突,但这应该永远不会发生,因为它只是搜索而不是找到它。

注意事项:

  1. 如果我禁用$ query-> useResultCache(true)我没有问题。
  2. 这是唯一一个在桌面上工作的过程。
  3. 这是代码中唯一将项目添加到表格中的位置。
  4. 此代码是从symfony2控制台命令调用的。
  5. Memcache是​​doctrine2的设置缓存。
  6. Memcached正在本地运行。
  7. 使用arraycache时也会产生错误。
  8. 此查询每秒运行多次。
  9.     class ItemRepository extends EntityRepository
        {
          public function findOrFetch($id)
          {
    
            $item = $this->findItem($id);
    
            if($item != null)
              return $item;
            else
              {
            $itemData = $this->fetchItem($id);
    
            $item = new Item();
            $item->setId($id);
            $item->setName($itemData['name']);
            $this->getEntityManager()->persist($item);
            $this->getEntityManager()->flush();
              }
          }
    
          private function findItem($id)
          {
            $query = $this
              ->getEntityManager()
              ->createQuery('SELECT i from MonkeyWire\WowProfToolsBundle\Entity\Item i WHERE i.id = ?1');
            $query->setParameter(1, $id);
            $query->useResultCache(true);
    
            return $query->getOneOrNullResult();
          }
    
          private function fetchItem($id)
          {
            $api = new Client();
            $api->setRequest(new Curl());
    
            try
              {
            $itemData = $api->getItemsApi()->getItem($id);
              }
            catch (NotFoundException $e)
              {
            $itemData['name'] = "na";
              }
    
            return $itemData;
          }
        }
    

1 个答案:

答案 0 :(得分:0)

听起来您可能需要在添加新项目时使结果缓存失效。

$query->expireResultCache();

根据您的存储库,您可能需要进行一些重组以适应这种情况:

class ItemRepository extends EntityRepository
{
    public $findQuery = null;
    ...
    public function findOrFetch($id)
    {
        ...
        $this->getEntityManager()->flush();
        $this->findQuery->expireResultCache();
          }
    }

    private function findItem($id)
    {
      $query = $this
        ->getEntityManager()
        ->createQuery('SELECT i from MonkeyWire\WowProfToolsBundle\Entity\Item i WHERE i.id = ?1');
      $query->setParameter(1, $id);
      $this->findQuery = $query;
      ...
    }
}