SQL php Rollback不起作用

时间:2014-05-18 19:04:59

标签: php sql

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

1 个答案:

答案 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。不幸的是 - 因为显然TRUNCATEDELETE慢得多,因为行将逐一处理。