请记住,MyISAM 表不支持回滚。
我刚刚花了整个下午的时间试图找出我的代码哪里出了问题 - 而实际上它一直都是正确的。
(PHP 5, PHP 7, PHP 8)
mysqli::rollback -- mysqli_rollback — 回滚当前事务
面向对象风格
过程式风格
回滚数据库的当前事务。
mysql
仅过程式风格:由 mysqli_connect() 或 mysqli_init() 返回的 mysqli 对象。
flags
MYSQLI_TRANS_COR_*
常量的位掩码。
name
如果提供,则执行 ROLLBACK/*name*/
。
如果启用了 mysqli 错误报告 (MYSQLI_REPORT_ERROR
) 并且请求的操作失败,则会生成警告。此外,如果模式设置为 MYSQLI_REPORT_STRICT
,则会抛出 mysqli_sql_exception 而不是警告。
版本 | 描述 |
---|---|
8.0.0 |
name 现在可以为 null。 |
请参阅 mysqli::begin_transaction() 示例。
注意:
此函数不适用于非事务性表类型(如 MyISAM 或 ISAM)。
这是一个解释回滚和提交函数强大功能的示例。
假设您希望确保所有查询在写入数据库之前都必须无错误地执行。
以下是代码
<?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; // 重复的主键值
// 现在让我们测试我们的控制变量
$all_query_ok ? $mysqli->commit() : $mysqli->rollback();
$mysqli->close();
?>
希望对您有所帮助!
如果您使用保存点 - 例如 savepoint($foo) - 请注意,尝试使用 rollback(0, $foo) 回滚到保存点,因为这会执行 "ROLLBACK /* $foo */" 而不是 "ROLLBACK TO `$foo`"。
手册页对此进行了明确说明,但很容易被忽视。
请改用:$mysqli->query("ROLLBACK TO `$foo`");
关于自动增量 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.