DocProine Metadata缓存ClassMetadata

时间:2016-06-12 10:00:06

标签: php symfony caching doctrine-orm redis

我的项目是在PHP7上开发的 使用

  • Symfony 3.1.0
  • Doctrine Bundle 1.6.3

我将所有 doctrine缓存驱动程序(query_cache_driver,result_cache_driver,metadata_cache_driver)更改为与 array 类型不同(例如memcached, redis)和正在执行 cache:clear 命令(仅在生产服务器上使用Debian8)。作为输出我得到了

[1]    15665 segmentation fault  bin/console cache:clear

然后我开始使用:

进行调试
bin/console doctrine:schema:validate

因为这个命令做了两件事(validateMapping,chechSync),而且这个命令也输出了一些有趣的东西:所有表都不同步,并且所有表都有相同的结构(所有元数据中的所有columnNames都是等于)

  1. 验证映射

    public function validateMapping()  {

    $errors = array();
    $cmf = $this->em->getMetadataFactory();
    $classes = $cmf->getAllMetadata();
    
    foreach ($classes as $class) {
        if ($ce = $this->validateClass($class)) {
            $errors[$class->name] = $ce;
        }
    }
    
    return $errors;
    

    }

  2. 检查同步

    公共功能schemaInSyncWithMetadata() {

    $schemaTool = new SchemaTool($this->em);
    
    $allMetadata = $this->em->getMetadataFactory()->getAllMetadata();
    
    return count($schemaTool->getUpdateSchemaSql($allMetadata, true)) == 0;
    

    }

  3. 这两种方法都使用 AbstractClassMetadataFactory :: getMetadataFor 方法。当所有元数据都清除时,此方法可以正常工作,但是当我第二次运行命令时,当调用此代码块时:

    $this->loadedMetadata[$realClassName] = $cached;
    
    $this->wakeupReflection($cached, $this->getReflectionService());
    

    现在我们可以看到, $ cached 被保存到内部数组中。 $ cached 目前,在此代码块中,是正确的数组,所有 columnNames 都是正确的。

    但是当第二次调用 getMetadataFor 时,在命令的第二步中,使用该内部数组的这段代码(在方法的开头)开始输出错误的元数据:(全部当所有引用的有关类的数据都正确时,columnNames是相等且不正确的)

    public function getMetadataFor($className)
    {
        if (isset($this->loadedMetadata[$className])) {
            return $this->loadedMetadata[$className];
        }
    

    为什么会这样?也许任何有用的解决方案?

0 个答案:

没有答案