Doctrine setAutoCommit(false)方法和"没有活动事务"信息

时间:2016-10-12 12:50:22

标签: symfony exception doctrine-orm transactions

编辑:问题是为什么使用setAutoCommit(false)是&#34的解决方案;没有活动的交易"例外。 忘掉这个问题,因为这不是正确的解决方案(至少在我的情况下)。我会在这里留下这个问题,以防有人遇到同样的问题。有关详细信息,请参阅下面的答案。

=====

以下代码在Symfony 2.7中运行良好,但在更新Symfony 2.8(以及最新的DoctrineBundle版本)之后,抛出了There is no active transaction异常:

private function getSynchronization() {
    $lock_repo = $this->entityManager->getRepository('MyAppBundle\Entity\DBLock');

    $this->entityManager->getConnection()->beginTransaction();

    try {
        $sync = $lock_repo->findOneByUser($this->getUser());

        if (!$lock) {
            $lock = new DBLock();
        } else {
            if ($lock->isActive()) {
                // ... Exception: Process already running
            }
            $expected_version = $lock->getVersion();
            $this->entityManager->lock($lock, LockMode::OPTIMISTIC, $expected_version);
        }

        $sync->setActive(false);

        $this->entityManager->persist($sync);
        $this->entityManager->flush();

        $this->entityManager->getConnection()->commit();

        // EXCEPTION on this line
        $this->entityManager->lock($lock, LockMode::NONE);
    }
    catch(\Exception $e) {
        $this->entityManager->getConnection()->rollback();
        throw new ProcessException($e->getMessage());
    }

    ...
}

经过一番搜索,我在another post找到了一个解决方案。添加以下行后一切正常:

private function getSynchronization() {
    $lock_repo = $this->entityManager->getRepository('MyAppBundle\Entity\DBLock');

    $this->entityManager->getConnection()->beginTransaction();

    // ADDED LINE
    $this->entityManager->getConnection()->setAutoCommit(false);

    try {
        ...

所以,问题不在于如何解决问题,而在于解决方案如何运作......

我对setAutoCommit()方法的Doctrine docs感到困惑:

  

要建立连接,请自动打开新事务   connect()以及commit()rollBack()后,您可以停用   setAutoCommit(false)

的自动提交模式

我不明白这一点。

这是否意味着,使用beginTransaction()时,使用commit()启动/创建的交易现已自动关闭?因此,为了能够在使用lock(...)之后使用commit(),我必须先开始新的交易。我可以通过再次调用beginTransaction()手动执行此操作,也可以通过之前设置setAutoCommit(false)自动执行此操作。 这是正确的吗?

这是对最新Doctrine版本的改变吗?我没有在更新说明中找到任何内容,在更新Symfony / Doctrine之前,代码工作正常。

非常感谢!

1 个答案:

答案 0 :(得分:1)

如前所述我遇到了这个问题,在从Doctrine 2.4更新到2.5之后,调用lock($lock, LockMode::NONE)突然引发了There is no active transaction异常。

我的解决方案是添加setAutoCommit(false),在调用commit()后会自动创建新的事务。它工作,异常没有再次发生。 然而,这不是真正的/正确的解决方案,它会产生其他问题作为副作用。

重新阅读我发现的Doctrine Update Notes后,正确的解决方案是使用lock($lock, null)代替lock($lock, LockMode::NONE)。这是学说2.4和2.5之间的BC Break。

也许我的问题和答案会帮助遇到同样问题的其他人。