我的问题 - 进程尝试更改已经更改并具有最新版本 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/

10-15 11:00