编辑:问题是为什么使用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之前,代码工作正常。
非常感谢!
答案 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。
也许我的问题和答案会帮助遇到同样问题的其他人。