3

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の行が存在しないため、更新はありません実際の結果、存在しない行を除くすべての行が更新されます。

事前にお詫び申し上げますが、オブジェクト指向プログラミングはまだ南極大陸です。

4

2 に答える 2

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');
}
于 2012-01-27T14:13:38.403 に答える
1

このコードは、例外がスローされた場合にのみトランザクションをロールバックします。

更新が失敗した場合false、例外ではなく を返します。

例外なしで試すことができます:

$try = $conn->commit();
if (!$try) {
   $conn->rollback();
}

または、結果が の場合に例外をスローしますfalse

于 2011-07-23T07:39:50.120 に答える