原则集自动提交(假)方法和"there is no active transaction"消息



EDIT:问题是关于为什么使用setAutoCommit(false)是"没有活动事务"异常的解决方案。忘记这个问题因为这不是正确的解决方案(至少在我的情况下)。我把这个问题留在这里,以防有人遇到同样的问题。

================

下面的代码在Symfony 2.7中工作得很好,但是在更新到Symfony 2.8(以及最新的DoctrineBundle版本)之后,抛出了一个There is no active transaction异常:

private function getSynchronization() {
    $lock_repo = $this->entityManager->getRepository('MyAppBundleEntityDBLock');
    $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());
    }
    ...
}

经过一番搜索,我在另一篇文章中找到了解决方案。添加以下行后,一切正常:

private function getSynchronization() {
    $lock_repo = $this->entityManager->getRepository('MyAppBundleEntityDBLock');
    $this->entityManager->getConnection()->beginTransaction();
    // ADDED LINE
    $this->entityManager->getConnection()->setAutoCommit(false);
    try {
        ...

所以,问题不是如何解决问题,而是如何解决问题…

我对setAutoCommit()方法的Doctrine文档感到非常困惑:

让一个连接自动打开一个新的事务connect()commit()rollBack()之后,可以禁用自动提交模式,setAutoCommit(false)

我不明白这个。

这是否意味着,使用beginTransaction()启动/创建的事务现在在使用commit()时自动关闭?因此,为了能够在使用commit()之后使用lock(...),我必须首先开始一个新的事务。我可以通过再次调用beginTransaction()手动做到这一点,或者通过设置setAutoCommit(false)之前自动做到这一点。是正确的吗?

这是最新教义版本中的一个变化吗?我没有在更新说明中找到任何关于Symfony/Doctrine的内容,在Symfony/Doctrine更新之前,代码工作得很好。

非常感谢!

如前所述,我遇到的问题,调用lock($lock, LockMode::NONE)后突然抛出There is no active transaction异常从原则2.4更新到2.5。

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

重读教义更新笔记后,我发现,正确的解决方案是使用lock($lock, null)而不是lock($lock, LockMode::NONE)。这是原则2.4和2.5之间的BC Break。

也许我的问题和回答可以帮助到遇到同样问题的人。

最新更新