mysqli::rollback

mysqli_rollback

(PHP 5, PHP 7, PHP 8)

mysqli::rollback -- mysqli_rollback回滚当前事务

描述

面向对象风格

public mysqli::rollback(int $flags = 0, ?string $name = null): bool

过程式风格

mysqli_rollback(mysqli $mysql, int $flags = 0, ?string $name = null): bool

回滚数据库的当前事务。

参数

mysql

仅过程式风格:由 mysqli_connect()mysqli_init() 返回的 mysqli 对象。

flags

MYSQLI_TRANS_COR_* 常量的位掩码。

name

如果提供,则执行 ROLLBACK/*name*/

返回值

成功时返回 true,失败时返回 false

错误/异常

如果启用了 mysqli 错误报告 (MYSQLI_REPORT_ERROR) 并且请求的操作失败,则会生成警告。如果此外将模式设置为 MYSQLI_REPORT_STRICT,则会抛出 mysqli_sql_exception 而不是警告。

变更日志

版本 描述
8.0.0 name 现在可以为空。

示例

参见 mysqli::begin_transaction() 示例。

注释

注意:

此函数不适用于非事务型表类型(如 MyISAM 或 ISAM)。

参见

添加注释

用户贡献的注释 5 notes

44
Steven McCoy
12 年前
请记住,MyISAM 表不支持回滚。

我花了一个下午试图找出代码出了什么问题,结果发现代码一直都是正常的。
34
Lorenzo - webmaster AT 4tour DOT it
15 年前
这是一个解释回滚和提交函数功能的示例。
假设您想确保所有查询都在写入数据库之前无错误执行。
以下是代码

<?php
$all_query_ok
=true; // 我们的控制变量

// 我们进行 4 次插入,最后一次会产生错误
// 如果至少有一个查询返回错误,我们更改我们的控制变量
$mysqli->query("INSERT INTO myCity (id) VALUES (100)") ? null : $all_query_ok=false;
$mysqli->query("INSERT INTO myCity (id) VALUES (200)") ? null : $all_query_ok=false;
$mysqli->query("INSERT INTO myCity (id) VALUES (300)") ? null : $all_query_ok=false;
$mysqli->query("INSERT INTO myCity (id) VALUES (100)") ? null : $all_query_ok=false; // 重复的 PRIMARY KEY 值

// 现在让我们测试我们的控制变量
$all_query_ok ? $mysqli->commit() : $mysqli->rollback();

$mysqli->close();
?>

希望对您有所帮助!
3
Yorick Phoenix
11 个月前
如果您使用保存点 - 例如 savepoint($foo) - 请注意,尝试使用 rollback(0, $foo) 回滚到保存点,因为这会执行 "ROLLBACK /* $foo */" 而不是 "ROLLBACK TO `$foo`"。

手册页面清楚地说明了这一点,但很容易被忽视。

相反,请使用:$mysqli->query("ROLLBACK TO `$foo`");
15
xcalibur at xcalibur dot dk
14 年前
关于自动递增 ID 和回滚的说明。
当使用事务并将数据插入包含自动递增 ID 列的表时,即使事务回滚,ID 也会递增。

如果执行了大量回滚,这可能会占用大量 ID。

示例
<?php
$mysqli
= new mysqli("localhost", "gugbageri", "gugbageri", "gugbageri");

/* 检查连接 */
if (mysqli_connect_errno()) {
printf("连接失败: %s\n", mysqli_connect_error());
exit();
}

/* 禁用自动提交 */
$mysqli->autocommit(FALSE);

/* 我们只创建一个测试表,包含一个自增主键列和一个内容列 */
$mysqli->query("CREATE TABLE TestTable ( `id_column` INT NOT NULL AUTO_INCREMENT , `content` INT NOT NULL , PRIMARY KEY ( `id_column` )) ENGINE = InnoDB;");

/* 提交新创建的表 */
$mysqli->commit();

/* 我们插入一行 */
$mysqli->query("INSERT INTO TestTable (content) VALUES (99)");

/* 我们提交插入的行 */
$mysqli->commit();

/* 我们再插入三行 */
$mysqli->query("INSERT INTO TestTable (content) VALUES (99)");
$mysqli->query("INSERT INTO TestTable (content) VALUES (99)");
$mysqli->query("INSERT INTO TestTable (content) VALUES (99)");

/* 我们进行回滚 */
$mysqli->rollback();

/* 我们插入一行 */
$mysqli->query("INSERT INTO TestTable (content) VALUES (99)");

/* 我们提交插入的行 */
$mysqli->commit();

if (
$result = $mysqli->query("SELECT id_column FROM TestTable")) {

while(
$row = $result->fetch_row()) {
printf("Id: %d.\n", $row[0]);
}
/* 释放结果 */
$result->close();
}

/* 删除表 TestTable */
$mysqli->query("DROP TABLE TestTable");

$mysqli->close();
?>

这将输出
Id: 1.
Id: 5.
-5
jd at dilltree dot com
15 年前
在使用事务时需要注意的是,不应该在事务后立即对同一张表执行普通查询(例如 DELETE)。如果事务回滚,DELETE 将执行并显示受影响的行,但即使 rollback() 命令在 DELETE 查询之前,该行也可能被神奇地重新插入。
To Top