SQL php回滚不起作用


SQL php Rollback does't work

我在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();

使用gettsqlaccess返回一个connection类型的对象,其中包含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();
    }

事务中的DDL

既然我们已经发现没有FK约束highscore -那么你的问题是由于MySQL 5.0.3以来,TRUNCATE表语法相当于删除所有行逻辑但不物理

如果这个表没有外键约束(你的情况),MySQL将通过快速方案产生TRUNCATE操作:它将做DROP表+ CREATE表。因此,虽然逻辑上删除所有行是相同的,但在如何维护操作方面,并不相同。

为什么会有这样的区别?因为MySQL在事务中不支持DDL。更准确地说,这样的操作不能回滚。对于MySQL, DDL操作将立即导致隐式提交。这就是为什么你会看到你的TRUNCATE语句:首先,即使你没有提交,也会提交;第二,回滚对它没有影响。

<<p> 解决方案/strong>

如果您仍然需要回滚操作,那么,不幸的是,您将需要使用DELETE语法而不是TRUNCATE。不幸的是——因为,很明显,DELETETRUNCATE慢得多,因为行将被逐一处理。