mysqliでトランザクション – 1件でも失敗したらロールバック
あるテーブルの項目「納期日」を更新したら、他のテーブルに存在している「納期日」も同じ日時で更新したい。
これらのテーブルはこの「納期日」でつながっているので、整合性を保つため 1 件でも失敗したら全て更新前の値に戻したい。
こういうときは、トランザクションを使う。 mysqli でのトランザクションの実装方法をメモ。
まず大前提として、使っている DB がトランザクションが使える InnoDB でないといけない。
MyISAM はトランザクションをサポートしてないので、トランザクションという処理を扱うことはできない。
mysqli でトランザクションの実装
MyISAM はトランザクションをサポートしてないので、トランザクションという処理を扱うことはできない。
try{
// トランザクション開始
$mysqli->begin_transaction();
try {
// table A の UPDATE
$sql1 = "UPDATE table A, table B SET A.deliverydate=? WHERE A.name=? A AND A.deliverydate = B.deliverydate";
$stm1=$mysqli->prepare($sql1);
$stm1->bind_param("ss", $delivery, $name);
$stm1->execute();
// table C の UPDATE
$sql2 = "UPDATE table C, table B SET C.deliverydate=? WHERE C.productno=? AND C.deliverydate = B.deliverydate";
$stm2=$mysqli->prepare($sql2);
$stm2->bind_param("si", $delivery, $productno);
$stm2->execute();
// table B の UPDATE
$stm3=$mysqli->prepare("UPDATE table B set deliverydate=? WHERE id=?");
$stm3->bind_param("si", $delivery, $id);
$stm3->execute();
// コミット
$mysqli->commit();
echo 'コミットしました。';
} catch( Exception $e ){
// エラーが発生したらロールバック
$mysqli->rollback();
throw $e;
// echo 'Error:'.$e->getMessage();
// exit;
}
} catch (Exception $e) {
throw $e;
}
トランザクションの開始には、 $mysqli->autocommit(FALSE);
を使って、オートコミットを無効にする方法もあるようだが、これを記述すると、これ以降の処理でもオートコミットが無効になる。