分离实体意味着什么?

时间:2015-09-16 09:17:30

标签: php doctrine-orm

阅读batch processing larger dataset in doctrine2,我偶然发现clear方法。

在那里,使用了这个例子:

<?php
$batchSize = 20;
$i = 0;
$q = $em->createQuery('select u from MyProject\Model\User u');
$iterableResult = $q->iterate();
foreach ($iterableResult as $row) {
    $user = $row[0];
    $user->increaseCredit();
    $user->calculateNewBonuses();
    if (($i % $batchSize) === 0) {
        $em->flush(); // Executes all updates.
        $em->clear(); // Detaches all objects from Doctrine!
    }
    ++$i;
}
$em->flush();

我很困惑clear语句为什么会这样做,所提供的信息对我也没有帮助。

同时阅读代码,并没有帮助,因为我不明白它的意图。

这是doctrine2实际调用的内容:

/**
 * Clears the UnitOfWork.
 *
 * @param string|null $entityName if given, only entities of this type will get detached.
 *
 * @return void
 */
public function clear($entityName = null)
{
    if ($entityName === null) {
        $this->identityMap =
        $this->entityIdentifiers =
        $this->originalEntityData =
        $this->entityChangeSets =
        $this->entityStates =
        $this->scheduledForSynchronization =
        $this->entityInsertions =
        $this->entityUpdates =
        $this->entityDeletions =
        $this->collectionDeletions =
        $this->collectionUpdates =
        $this->extraUpdates =
        $this->readOnlyObjects =
        $this->visitedCollections =
        $this->orphanRemovals = array();

        if ($this->commitOrderCalculator !== null) {
            $this->commitOrderCalculator->clear();
        }
    } else {
        $visited = array();

        foreach ($this->identityMap as $className => $entities) {
            if ($className !== $entityName) {
                continue;
            }

            foreach ($entities as $entity) {
                $this->doDetach($entity, $visited, false);
            }
        }
    }

    if ($this->evm->hasListeners(Events::onClear)) {
        $this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->em, $entityName));
    }
}

所以我的问题是:

对象与教义分离是什么意思?有什么影响?使用clear有什么好处?

1 个答案:

答案 0 :(得分:1)

查看学说参考文档,看起来clear()将有效地释放它正在处理的所有对象的EntityManager

所以我的理解是flush()提交数据库,clear()从内存中释放(至少就教义而言)。

查看EntityManager的{​​{1}}方法herehere (lines 421 to 435)的文档。反过来调用clear()
因此,对于UnitOfWork,请查看herehere (lines 1881 an on)

仅供参考,您可以从文档(最新的2.5版本)获取UnitOfWork中的代码:

EntityManager

和UnitOfWork:

 /**
  * Clears the EntityManager. All entities that are currently managed
  * by this EntityManager become detached.
  *
  * @param string $entityName
  */
 public function clear($entityName = null)
 {
     if ($entityName === null) {
         $this->unitOfWork->clear();
     } else {
         //TODO
         throw new ORMException("EntityManager#clear(\$entityName) not yet implemented.");
     }
 }

所以当文档说:

  

清除EntityManager。当前由此EntityManager管理的所有实体都将分离。

我的理解是,他们所说的“超然”是指实体经理不再保留这些实体的记录。因此,如果没有其他任何内容,他们可以收集垃圾。

如果你想确保它确实收集垃圾并有效地释放内存,那么你最好在/** * Clears the UnitOfWork. */ public function clear() { $this->identityMap = $this->entityIdentifiers = $this->originalEntityData = $this->entityChangeSets = $this->entityStates = $this->scheduledForDirtyCheck = $this->entityInsertions = $this->entityUpdates = $this->entityDeletions = $this->collectionDeletions = $this->collectionUpdates = $this->extraUpdates = $this->readOnlyObjects = $this->orphanRemovals = array(); if ($this->commitOrderCalculator !== null) { $this->commitOrderCalculator->clear(); } if ($this->evm->hasListeners(Events::onClear)) { $this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->em)); } } 进程循环的某个地方调用gc_collect_cycles()