我的问题 - 进程尝试更改已经更改并具有最新版本 ID 的实体。当我在 UnitOfWork 的 commit() 的代码中执行 flush() 时,会引发 OptimisticLockException 并通过 catch-all 块在同一位置捕获。并在这个 catch 原则中关闭 EntityManager。
如果我想跳过这个实体并从 ArrayCollection 继续另一个实体,我不应该使用flush()?
尝试重新创建 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());
然后执行 flush() 我得到 OptimisticLockException 和关闭的实体管理器。
如果我做
$this->getContainer()->get('doctrine')->resetManager();
$em = $doctrine->getManager();
旧数据未在此实体管理器中注册,我什至无法在数据库中写入日志,出现错误:
[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Undefined index: 00000000514cef3c000000002ff4781e
最佳答案
您应该在尝试刷新之前检查实体版本以避免异常。换句话说,如果锁定失败,您不应该调用 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 docs optimistic locking 中的示例
关于doctrine-orm - 发生 OptimisticLockException 时如何避免关闭 EntityManager?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32263334/