我有一个需要脚本的脚本获取数据库中的条目列表,然后迭代那些在另一个表中创建新条目的条目,如果它们不存在。
目前在做:
foreach($entries as $entry){
$newItem = new Item();
$newItem->setAttribute($entry->getAttribute());
$entityManager->persist($newItem);
try{
$entityManager->flush();
} catch(Exception $e){
if(!strpos($e->getMessage(),'Duplicate')){
throw $e;
}
$entityManager = $this->getDoctrine()->getManager();
//refreshes the entity manager
}
}
但是这样做是非常耗时的,有1000个条目,脚本有时需要超过10分钟的时间才能完成。我已经看到其他帖子建议在这样的批处理处理时,每20个左右都会冲洗一次问题,这是如果这20个是重复的,那么整个交易就会消失,我不确定我将如何返回并尝试并尝试和尝试在再次重新提交之前,找到排除它的有问题的条目。
对此的任何帮助将不胜感激。
您可以做一个SELECT
来获取数据库中已经存在的记录,然后跳过这些记录。此外,尝试仅执行flush()
和clear()
,或者使用批处理大小进行播放。我还建议使用交易(如果您使用InnoDB)。
$this->_em->getConnection()
->beginTransaction();
try {
$created = array(/* all primary keys that already exist */);
$i = 1;
$batchSize = sizeof($entries);
foreach ($entries as $entry) {
if (in_array($entry->getMyPrimaryKey(), $created)) {
continue;
}
$newItem = new Item();
$newItem->setAttribute($entry->getAttribute());
$entityManager->persist($newItem);
if (($i % $batchSize) == 0) {
$this->_em->flush();
$this->_em->clear();
}
$i++;
}
$this->_em->getConnection()
->commit();
} catch (Exception $e) {
$this->_em->getConnection()
->rollback();
$this->_em->close();
throw new RuntimeException($e->getMessage());
}