MySQL ROLLBACK doesn't actually rollback

I have the following PHP code:

$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();

      

Transactions work fine for regular updates / inserts, but the above code is not for some reason. When the above error occurs, I am left with a completely empty table reservations

. I read on the PDO :: beginTransaction page that "some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued as part of a transaction." The MySQL manual has a list of "Data Definition Statements" which I would assume is the same as mentioned above in the DDL that lists CREATE TABLE

, but I am creating a temporary table. Is there a way to get around this?

Also, does the fact that I was left with an empty table reservations

indicate that there was a commit after the request DELETE QUICK FROM reservations

?

Edit . One more note: the line INSERT INTO reservations

also throws the following error:

The requests cannot be completed while other unbuffered requests are active. Consider using PDOStatement :: fetchAll (). Also, if your code will only work with mysql, you can enable query buffering by setting the PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY attribute.

I've tried doing it $dbh->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , true);

, but it doesn't seem to affect it. I am guessing it will be transaction related, but I'm not sure. Anyone can determine what exactly is causing this error?

+3


source to share


1 answer


Your operator OPTIMIZE TABLE

triggers an implicit commit.

I'm not sure what you are trying to do, but it looks like you can shorten your code to:

$dbh->exec("OPTIMIZE TABLE `reservations`");

      



All other code just makes things harder as there is no amplification.

I also assume that you are using InnoDB tables because MyISAM tables will not support transactions anyway. Every DDL or DML operation on a MyISAM table is implicitly committed immediately.

By the way, buffered queries have nothing to do with transactions. They involve fetching SELECT results one row at a time, compared to putting the entire result set into memory in PHP and then iterating through it. See explanation at: http://php.net/manual/en/mysqlinfo.concepts.buffering.php

+2


source







All Articles