我在php中有以下内容:
try {
// INSERT FETCHED LIST INTO ARCHIVE
$stmt1 = $sql->prepare('INSERT INTO hsarchive (LIST) VALUES (?)');
$stmt1->bind_param("s",$total);
$stmt1->execute();
$stmt2 = $sql->prepare('TRUNCATE TABLE highscore');
$stmt2->execute();
$sql->rollback();
$stmt1->close();
$stmt2->close();
} catch (Exception $e) {
echo "error";
$sql->rollback();
}
引擎是InnoDB,连接启动如下:
$sql = getSQLAccess();
$sql->autocommit(false);
$sql->begin_transaction();
使用getSQLAccess返回与user,pw等类型连接的对象。
无论我如何旋转它,表格都会被截断,列表会被插入到存档中。我尝试转换关闭语句的位置,正如您所看到的,我目前甚至没有提交,因为我试图弄清楚为什么回滚不起作用。
任何?
编辑:根据最佳答案,这将是最佳选择:
try {
// INSERT FETCHED LIST INTO ARCHIVE
$stmt = $sql->prepare('INSERT INTO hsarchive (LIST) VALUES (?)');
$stmt->bind_param("s",$total);
$stmt->execute();
$stmt->close();
$stmt = $sql->prepare('DELETE FROM highscore');
$stmt->execute();
$stmt->close();
$sql->commit();
} catch (Exception $e) {
$sql->rollback();
}
答案 0 :(得分:3)
交易中的DDL
由于我们已经发现没有FK约束到表highscore
- 那么您的问题就是因为MySQL 5.0.3 ,TRUNCATE
table语法相当于删除所有行逻辑但不是物理
如果此表(您的情况)没有限制执行此操作的外键约束,MySQL将通过快速方案生成TRUNCATE
操作:它将执行DROP
表+ {{1} }表。因此,从逻辑上讲,它与删除所有行相同,但在维护操作方面不一样。
为什么这有区别?因为MySQL doesn't support DDL在事务中。更准确地说,此类操作无法回滚。对于MySQL,DDL操作will cause immediate implicit commit。这就是为什么你看到你的CREATE
声明:首先,即使你没有提交也是如此;第二,回滚对它没有影响。
<强>解决方案强>
如果您仍然需要回滚操作,那么,遗憾的是,您需要使用TRUNCATE
语法而不是DELETE
。不幸的是 - 因为显然TRUNCATE
比DELETE
慢得多,因为行将逐一处理。