对于 MySQL 用户来说,这里有一个快速(也许很明显)的说明;
如果您使用 MyISAM 表来测试回滚,并且它没有按预期工作,不要感到困惑。
rollBack() 和 beginTransaction() 都会返回 TRUE,但回滚不会发生。
将表转换为 InnoDB 并再次运行测试。
(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.1.0)
PDO::rollBack — 回滚事务
回滚当前事务,该事务由 PDO::beginTransaction() 初始化。
如果数据库设置为自动提交模式,则此函数将在回滚事务后恢复自动提交模式。
一些数据库(包括 MySQL)在事务中发出数据定义语言 (DDL) 语句(如 DROP TABLE 或 CREATE TABLE)时会自动发出隐式 COMMIT。隐式 COMMIT 将阻止您回滚事务边界内的任何其他更改。
此函数没有参数。
示例 #1 回滚事务
以下示例开始一个事务,并发出两个修改数据库的语句,然后回滚更改。但是,在 MySQL 上,DROP TABLE 语句会自动提交事务,因此事务中的所有更改都不会回滚。
<?php
/* 开始事务,关闭自动提交 */
$dbh->beginTransaction();
/* 更改数据库架构和数据 */
$sth = $dbh->exec("DROP TABLE fruit");
$sth = $dbh->exec("UPDATE dessert
SET name = 'hamburger'");
/* 识别错误并回滚更改 */
$dbh->rollBack();
/* 数据库连接现在恢复为自动提交模式 */
?>
对于 MySQL 用户来说,这里有一个快速(也许很明显)的说明;
如果您使用 MyISAM 表来测试回滚,并且它没有按预期工作,不要感到困惑。
rollBack() 和 beginTransaction() 都会返回 TRUE,但回滚不会发生。
将表转换为 InnoDB 并再次运行测试。
以下是如何在使用 MySQL 的 InnoDB 表时测试事务是否已启动的方法。如果您使用的是 MySQL 的 MyISAM 表,则它会失败,因为 MyISAM 表不支持事务,但也不会在使用它们时返回错误。
<?
// 开始事务
$dbh->beginTransaction();
// 要验证事务是否已启动,请尝试创建一个(对 InnoDB 非法的)嵌套事务。
// 如果它有效,则第一个事务没有正确启动或不受支持(例如在 MyISAM 表上)
try {
$dbh->beginTransaction();
die('取消,事务未正确启动');
} catch (PDOException $e) {
print "事务正在运行(因为尝试另一个事务失败了)\n";
}
?>
如果任何阅读本文的人因发现他们的 MySQL 表是 MyIsam 而不是 InnoDb 而感到恐慌,请不要担心...您可以使用以下查询非常轻松地更改存储引擎
ALTER TABLE your_table_name ENGINE = innodb;
由于“如果当前没有活动事务,则调用此方法会出错”,因此有一个方法来返回当前事务是否处于活动状态(即使不是必需的)会很有用。
try {
$dbh->beginTransaction();
...
} catch (PDOException $e) {
if ($dbh->isTransactionActive()) // 此函数不存在
$dbh->rollBack();
...
}
与此同时,我使用以下代码
...
} catch (PDOException $e) {
try { $dbh->rollBack(); } catch (Exception $e2) {}
...
}
它并不那么优雅,但效果很好。