我有以下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)在事务中发出数据库定义语言(DDL)语句(如DROP TABLE或CREATE TABLE)时自动发出隐式COMMIT ”。 MySQL manual有一个“数据定义语句”列表,我假设它与上面提到的列出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);
,但这似乎并没有影响它。我假设它与交易有关,但我不确定。任何人都可以确定导致此错误的确切原因吗?
答案 0 :(得分:2)
您的OPTIMIZE TABLE
语句导致隐式提交。
我不确定您要做什么,但看起来您可以将代码缩短为:
$dbh->exec("OPTIMIZE TABLE `reservations`");
所有其他代码只是让工作更复杂,没有收获。
我还假设您正在使用InnoDB表,因为MyISAM表无论如何都不支持事务。 MyISAM表上的每个DDL或DML操作都会立即隐式提交。
顺便说一下,缓冲查询与事务无关。它们与每次获取一行SELECT结果集有关,而不是在PHP中将整个结果集提取到内存中,然后迭代它。请参阅:http://php.net/manual/en/mysqlinfo.concepts.buffering.php
中的说明