我有以下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::开始交易页面上看到,“当在事务中发出数据库定义语言(DDL)语句(如DROP或CREATE )时,某些数据库(包括MySQL )会自动发出隐式提交”。MySQL手册有一个“数据定义语句”列表,我假设它与上面提到的列出CREATE TABLE的DDL相同,但我只是创建一个临时表。有办法绕过这件事吗?
另外,留给我一个空的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);,但这似乎并没有影响它。我认为这与交易有关,但我不确定。有人能准确地指出到底是什么导致了这个错误吗?
发布于 2013-01-29 01:57:51
OPTIMIZE TABLE语句导致隐式提交。
我不知道您到底想要做什么,但是看起来您可以将代码缩短到:
$dbh->exec("OPTIMIZE TABLE `reservations`");所有其他代码只是使工作变得更加复杂,而没有任何好处。
我还假设您使用的是InnoDB表,因为MyISAM表无论如何都不支持事务。MyISAM表上的每个DDL或DML操作都会立即隐式提交。
顺便说一下,缓冲查询与事务无关。它们与每次获取SELECT结果集有关,而不是将整个结果集提取到PHP中的内存中,然后迭代。参见解释:http://php.net/manual/en/mysqlinfo.concepts.buffering.php
https://stackoverflow.com/questions/14574037
复制相似问题