【问题标题】:How PDO rollbacks the queries before executing rollBack() function?PDO 如何在执行 rollBack() 函数之前回滚查询?
【发布时间】:2016-07-26 00:52:09
【问题描述】:

这是我的脚本:

try {
    $dbh_con->beginTransaction();

        $stmt1 = $dbh_conn->prepare("UPDATE activate_account_num SET num = num + 1");
        $stmt1->execute();

        $stmt2 = $dbh_con->prepare("SELECT user_id FROM activate_account WHERE token = ?");
        $stmt2->execute(array($token));
        $num_rows = $stmt2->fetch(PDO::FETCH_ASSOC);

        if ( $num_rows['user_id'] ){
            $_SESSION['error'] = 'all fine';

        } else {
            $_SESSION['error'] = 'token is invalid';
            header('Location: /b.php');
             exit();
        }

    $dbh_con->commit();

    header('Location: /b.php');
    exit();

} catch(PDOException $e) {

    $dbh_con->rollBack();

    $_SESSION['error'] = 'something is wrong';
    header('Location: /b.php');
    exit();
}

如您所见,else 块包含 exit() 函数。所以当else块执行时,那么rollBack();函数肯定不会执行,因为在执行rollBack();之前,脚本会退出。但令人惊讶的是UPDATE 语句回滚.. 怎么样?

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    当所有更改必须同时发生或根本不发生更改时使用事务。

    为了在突然停止的情况下保持数据库的完整性(例如:脚本意外退出、服务器崩溃、电源被切断......),事务的实现将通过在@之前不进行任何更改来保护您987654321@ 被调用。当您execute 中间查询时,更改实际上并没有影响数据库,而是处于不确定状态。如果你没有提交就退出,那么地狱就被扔掉了。

    当你rollBack() 时,地狱也只是被扔掉了。

    【讨论】:

    • 很好的解释.. +1
    • 是的,这个解释在概念上是正确的。但是对于它的价值,InnoDB 内部真正做的是将原始数据复制到“回滚段”,将更新应用到适当的数据(预计您将提交大部分更改)。如果进行回滚,InnoDB 会在后台工作,将回滚段中保留的副本恢复到表中的原始位置。
    • 原因是您描述的“边缘”概念需要很大才能容纳更改,因为事务中的工作量没有限制。它必须持久保存。这意味着您最终的 COMMIT 非常快,因为数据已经保存。它只需要更新事务的状态。回滚段中的过时数据逐渐被垃圾收集。
    • @BillKarwin 我进行了简化,以使答案从 DB 消费者的角度有用。不过,您的回答提出了一个问题:如果突然断电,未提交的更改会在数据库中持续存在吗?我可能会误解,但如果更新实际上应用于数据,这是否意味着另一个查询数据库的脚本会看到未提交的更改?
    • 另一个脚本看不到它不应该看到的未提交的更改。修改后的页面使用应用更改的事务进行注释。我的事务检查页面上的事务 id,知道它不应查看该数据的该版本,而是跟随该页面上的指针指向存储在回滚段中的数据的先前版本。
    【解决方案2】:

    在正常情况下,脚本退出时php客户端会断开连接,这将导致MySQL回滚。

    【讨论】:

      猜你喜欢
      • 2012-12-09
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      • 2013-11-05
      • 2019-12-27
      • 1970-01-01
      相关资源
      最近更新 更多