は私のスクリプトです:PDOがrollBack()関数を実行する前にクエリをロールバックする方法はありますか?ここ
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"の概念は、トランザクションに含まれる可能性のある作業の量に制限がないので、変更を保持するためには膨大なものである必要があるからです。それは永続的に救われなければならない。これは、データがすでに保存されているため、最終的なコミットがかなり早いことを意味します。トランザクションの状態を更新するだけです。ロールバック・セグメント内の古いデータは、徐々にガーベジ・コレクションされます。 –