我真的不明白如何在DBAL中进行交易
我有以下脚本,根据行的ID更新列。我放了一个表中不存在的假id,(因此无法进行更新)但是第一次更新是在事务发生的情况下提交的。如果其中一个失败,我希望所有事务都失败。
$conn -> beginTransaction();
try{
$try = $conn->prepare("update table set column = '123' where id = 0"); //column exists
$try->execute();
$try = $conn->prepare("update table set column = '123' where id = 1"); //column exists
$try->execute();
$try = $conn->prepare("update table set column = '123' where id = 120"); //column does not exists
$try->execute();
$try = $conn->commit();
}
catch(Exception $e) {
$try = $conn->rollback();
throw $e;
}
预期结果,因为id = 120的行不存在更新 实际结果,所有行都会更新,但不存在的行除外。
我提前道歉,但面向对象编程对我来说仍然是南极洲。
答案 0 :(得分:3)
我知道这个问题很老了,所以如果有人在未来遇到类似的问题,我会稍微解释一下,因为这种行为不是错误。
$try = $conn->prepare("update table set column = '123' where id = 120"); //column does not exists
$try->execute();
这里更新条件引用了一个不存在的列,因此查询不会失败,它将更新0(零)行;在Doctrine中,execute()
方法返回受影响的行数。
您可以抛出一个异常来触发回滚。
$try = $conn->prepare("update table set column = '123' where id = 120"); //column does not exists
$affected = $try->execute();
if ($affected == 0) {
throw new Exception('Update failed');
}
答案 1 :(得分:1)
此代码仅在抛出异常时回滚事务。
如果更新失败,则返回false
,而不是异常。
您可以尝试没有例外:
$try = $conn->commit();
if (!$try) {
$conn->rollback();
}
结果为false
时或抛出异常。