我有以下的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列出了“数据定义语句”的列表,我认为这与上面提到的DDL相同,其中列出了CREATE TABLE
,但我只创建了一个临时表。有没有什么办法可以解决这个问题?
此外,我留下了一个空的reservations
表,这是否表明在DELETE QUICK FROM reservations
查询之后发生了提交?
编辑:另外,INSERT INTO reservations
行也会产生以下错误:
OPTIMIZE TABLE
是不够的。然而,当我多年前编写这段代码时,我使用的是MyISAM,为了确保数据不会损坏,我创建了一个临时表,然后对其进行操作(大约15000个查询),最后将临时表复制到真正的表中,因为这样比在其他查询中出现问题或超时更少风险。但现在我想起来了,我可以在一个事务中完成所有操作,完全不需要使用临时表。 - Mike