2015-08-28 1 views
1

Моя проблема - попробуйте изменить сущность, которая уже изменилась и имеет новый идентификатор версии. Когда я делаю flush() в моем коде в commit(), повышающем OptimistLockException UnitOfWork и перехватывая в том же месте блоком catch-all. И в этой доктрине catch, закрывающей EntityManager. Если я хочу пропустить эту сущность и продолжить с другой из ArrayCollection, я не должен использовать flush()?Как избежать закрытия EntityManager при возникновении исключения OptimisticLockException?

Попробуйте обновить EntityManager:

}catch (OptimisticLockException $e){ 
    $this->em = $this->container->get('doctrine')->getManager(); 
    echo "\n||OptimisticLockException."; 
    continue; 
} 

И еще получить

[Doctrine\ORM\ORMException] 
The EntityManager is closed. 

Странно.

Если я сделать

$this->em->lock($entity, LockMode::OPTIMISTIC, $entity->getVersion()); 

, а затем сделать флеш() я получаю OptimisticLockException и закрытого менеджера объекта. если я сделать

$this->getContainer()->get('doctrine')->resetManager(); 
$em = $doctrine->getManager(); 

Старых данные незарегистрированного с этим менеджером сущности и я даже не могу писать журналы в базе данных, я получаю ошибку:

[Symfony\Component\Debug\Exception\ContextErrorException] 
Notice: Undefined index: 00000000514cef3c000000002ff4781e 
+0

Или я должен заново EntityManager в блоке поймать в моем коде? – Hayate

ответ

1

Вы должны проверить версию сущности, прежде чем пытаться очистить чтобы избежать исключения. Другими словами, вы не должны вызывать метод flush(), если блокировка не удалась.

Вы можете использовать метод EntityManager#lock() для проверки того, можете ли вы удалить объект или нет.

/** @var EntityManager $em */ 
    $entity = $em->getRepository('Post')->find($_REQUEST['id']); 

    // Get expected version (easiest way is to have the version number as a hidden form field) 
    $expectedVersion = $_REQUEST['version']; 

    // Update your entity 
    $entity->setText($_REQUEST['text']); 

    try { 
     //assert you edit right version 
     $em->lock($entity, LockMode::OPTIMISTIC, $expectedVersion); 

     //if $em->lock() fails flush() is not called and EntityManager is not closed 
     $em->flush(); 
    } catch (OptimisticLockException $e) { 
     echo "Sorry, but someone else has already changed this entity. Please apply the changes again!"; 
    } 

Проверьте пример в Doctrine документации optimistic locking

+0

Добавить информацию в вопрос. – Hayate

+1

Я читал это в документах, я это понимаю. Я не хочу эхо «извиняться» и перестать работать. Я получаю много данных, и я не хочу запрашивать все данные снова из-за одного объекта. В блоке catch EntityManager закрыт. Хорошо, я могу сбросить его и создать снова. Но все данные, незарегистрированные в новом EntityManager, и я больше не могу работать с этими данными. – Hayate

+0

В моем примере я сделал lock() для проверки только для одного объекта, но в вашем случае вам нужно выполнить проверку для всех объектов в вашей коллекции. Если блокировка для какого-либо объекта выходит из строя, вам необходимо решить, как его решить (перезагрузить объект из базы данных, предупредить пользователя и т. Д.). Вы не должны вызывать flush(), если какой-либо объект не прошел проверку блокировки. – kormik