次のPHPコードがあります。
$dbh->beginTransaction();
$dbh->exec("LOCK TABLES
`reservations` WRITE, `settings` WRITE");
$dbh->exec("CREATE TEMPORARY TABLE
temp_reservations
SELECT * FROM reservations");
$dbh->exec("ALTER TABLE
`temp_reservations`
ADD INDEX ( conf_num ) ; ");
// [...Other stuff here with temp_reservations...]
$dbh->exec("DELETE QUICK FROM `reservations`");
$dbh->exec("OPTIMIZE TABLE `reservations`");
$dbh->exec("INSERT INTO `reservations` SELECT * FROM temp_reservations");
var_dump(GlobalContainer::$dbh->inTransaction()); // true
$dbh->exec("UNLOCK TABLES");
$dbh->rollBack();
トランザクションは通常の更新/挿入では正常に機能していますが、上記のコードは何らかの理由で機能していません。上記のエラーが発生すると、完全に空のreservations
テーブルが残ります。PDO::beginTransactionページで、「MySQL を含む一部のデータベースは、DROP TABLE や CREATE TABLE などのデータベース定義言語 (DDL) ステートメントがトランザクション内で発行されると、暗黙的な COMMIT を自動的に発行する」と読みました。MySQLのマニュアルには「データ定義ステートメント」のリストがあります。これは、上記のリストのDDLと同じであると想定していますCREATE TABLE
が、一時テーブルを作成しているだけです。これを回避する方法はありますか?
また、空のテーブルが残っているという事実は、クエリの後reservations
にコミットが発生したことを示していますか?DELETE QUICK FROM reservations
編集:追加のメモとして、このINSERT INTO reservations
行は次のエラーも生成します:
バッファリングされていない他のクエリがアクティブな間は、クエリを実行できません。PDOStatement::fetchAll() の使用を検討してください。または、コードが mysql に対してのみ実行される場合は、PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 属性を設定して、クエリのバッファリングを有効にすることができます。
やってみ$dbh->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , true);
ましたが、影響はないようです。取引に何らかの関係があると推測していますが、よくわかりません。このエラーの原因を正確に特定できる人はいますか?