Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony2:交易失败,并带有“;没有活动的交易。”;_Symfony_Pdo_Transactions_Doctrine_Rollback - Fatal编程技术网

Symfony2:交易失败,并带有“;没有活动的交易。”;

Symfony2:交易失败,并带有“;没有活动的交易。”;,symfony,pdo,transactions,doctrine,rollback,Symfony,Pdo,Transactions,Doctrine,Rollback,我花了几个小时试图解决这个问题。谷歌和Stackoverflow也帮不了什么忙。所以这里欢迎任何建议 在更新两个表时,我尝试对事务应用回滚逻辑: 一般而言,守则如下: // ... $em = $this->getDoctrine()->getEntityManager(); $em->getConnection()->beginTransaction(); foreach($dataArr as $data) { $userObj = $em->getR

我花了几个小时试图解决这个问题。谷歌和Stackoverflow也帮不了什么忙。所以这里欢迎任何建议

在更新两个表时,我尝试对事务应用回滚逻辑:

一般而言,守则如下:

// ...
$em = $this->getDoctrine()->getEntityManager();
$em->getConnection()->beginTransaction();

foreach($dataArr as $data) {
    $userObj = $em->getRepository('AcmeBundle:User')->find($userId);
    $userObj->setActive(1);
    $em->persist($userObj);
    $em->getConnection()->commit();
}

$storeObj = $em->getRepository('AcmeBundle:Store')->find($storeId);
$storeObj->setIsOpen(1);
$em->persist($storeObj);
$em->getConnection()->commit();

try {

    $em->flush();
    $em->clear();    

} catch(Exception $e) {

    $em->getConnection()->rollback();
    $em->close();
    throw $e;

}
我的PDO驱动程序已启用,在没有事务的情况下进行更新可以按预期工作,但一旦我启动Intransaction()并尝试提交(),一切都不起作用,并且我得到消息,则没有活动事务。异常


一些消息来源建议只使用commit()而不使用persist(),但这没有任何区别。我可能在这里做了一些非常愚蠢的事情,但我就是看不出它是什么。

正如@prodigitalson正确地建议的那样,我需要在flush()之前执行commit(),以便执行查询。因此,现在的工作代码是:

$em = $this->getDoctrine()->getEntityManager();
$em->getConnection()->beginTransaction();

foreach($dataArr as $data) {
    $userObj = $em->getRepository('AcmeBundle:User')->find($userId);
    $userObj->setActive(1);
    $em->persist($userObj);
    // this is no longer needed
    // $em->getConnection()->commit();
}

$storeObj = $em->getRepository('AcmeBundle:Store')->find($storeId);
$storeObj->setIsOpen(1);
$em->persist($storeObj);
// this is no longer needed
// $em->getConnection()->commit();

try {

    // Do a commit before the FLUSH
    $em->getConnection()->commit();
    $em->flush();
    $em->clear();    

} catch(Exception $e) {

    $em->getConnection()->rollback();
    $em->close();
    throw $e;

}
之后

你必须写:

$this->em->getConnection()->setAutoCommit(false);

它适用于我:)

我曾经意外地得到这个错误 通过执行以下操作:

$em->getConnection()->beginTransaction();
try {
    $em->persist($entityA);
    $em->flush();

    $em->persist($entityB);
    $em->flush();

    $em->getConnection()->commit();
    //exception thrown here
    $mailer->send($from, $to, $subject, $text);
} catch (\Exception($ex)) {
    $em->getConnection()->rollback();
}

因此,您已经猜到,在提交之后不应该有任何代码,就像这个任意代码($mailer service,在我们的示例中)抛出的情况一样,在执行catch块之前,异常事务将被关闭。这可能会为某人节省一两分钟:)

自的1.5.2版以来,您可以配置在项目配置中使用的连接

# app/config/config.yml (sf2-3) or config/doctrine.yaml (sf4)
doctrine:
    dbal:
        auto_commit: false

我认为您需要在提交之前进行刷新,因为提交是在DB级别,persist除了在下一次刷新时将实体标记为持久化之外,实际上不做任何事情,而flush实际执行查询,您必须先执行某种查询才能提交。@prodigitalson您完全正确:我从foreach循环中删除了
$em->getConnection()->commit()
,然后在
$em->flush()
之前使用它。现在很有魅力。非常感谢。嗯,要么你的解决方案出错了,要么我错了。我的建议是先冲水,然后承诺。就我所认为的问题而言,您所解决的问题与您最初的代码几乎没有什么不同。如果你发布的内容有效,那么肯定是你的多个提交声明,因为这是本质上的改变。而且你不应该用答案修改你的问题。。。您可以回答自己的问题,尽管您需要等待一段时间才能将其标记为已接受的答案。@prodigitalson我将解决方案移到了自己的答案中,谢谢。但实际上,一旦我删除了persist()之后的commit(),并且在flush()之前只使用了一个commit(),就可以了。不幸的是,这使我的数据装置无法刷新到数据库中。
# app/config/config.yml (sf2-3) or config/doctrine.yaml (sf4)
doctrine:
    dbal:
        auto_commit: false