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。
也许我的问题和回答可以帮助到遇到同样问题的人。