这里是我的脚本:在执行rollBack()函数之前,PDO如何回滚查询?
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
声明回滚..如何?
很好的解释.. +1 – stack
是的,这个解释在概念上是正确的。但是值得一提的是,InnoDB在内部真正做的是将原始数据复制到“回滚段”,将更新应用到数据中(预计您将承担大部分更改)。如果您执行回滚,InnoDB将在后台运行,以将保留在回滚段中的副本恢复到表中的原始位置。 –
原因是您所描述的“limbo”概念对于变更需要巨大的努力,因为交易中可能的工作量没有限制。它必须持久保存。这意味着您的最终COMMIT非常快,因为数据已经保存。它只需更新交易的状态。回滚段中的过时数据逐渐被垃圾收集。 –