【发布时间】:2015-08-27 12:01:49
【问题描述】:
我花了几个小时试图解决这个问题。谷歌和 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 驱动程序已启用,没有事务的更新按预期工作,但是一旦我 beginTransaction() 并尝试 commit() 没有任何工作,我得到 There is no active transaction. 异常。
一些消息来源建议只使用 commit() 而不使用 persist() ,但它没有任何区别。我可能在这里做了一些非常愚蠢的事情,但我就是看不到它是什么。
【问题讨论】:
-
我相信你需要在提交之前刷新,因为提交是在数据库级别,除了标记实体在下一次刷新时持久化之外,persist 并没有真正做任何事情,而刷新实际上执行查询,并且您必须先执行某种查询,然后才能提交。
-
@prodigitalson 你说的完全正确:我从 foreach 循环中删除了
$em->getConnection()->commit(),然后就在$em->flush()之前使用了它。现在就像一个魅力。谢谢! -
嗯,要么你的解决方案出错,要么我错了。我的建议是刷新,然后提交。就我认为的问题而言,您解决的问题与您的初始代码略有不同。如果您发布的内容有效,那么它一定是您拥有的多个提交语句,因为那是本质上的变化。
-
另外你不应该用答案来修改你的问题......你可以回答你自己的问题,尽管在你可以将它标记为接受的答案之前有一个等待期。
-
@prodigitalson 我将解决方案移至自己的答案,谢谢。但实际上,一旦我删除了在persist() 之后的commits() 并且在flush() 之前只使用了一个commit() 就可以了。
标签: symfony pdo transactions doctrine rollback