请注意,调用 mysqli::commit() 不会自动将 mysqli::autocommit() 设置回 'true'。
这意味着任何跟随 mysqli::commit() 的查询将在您的脚本退出时回滚。
(PHP 5, PHP 7, PHP 8)
mysqli::commit -- mysqli_commit — 提交当前事务
面向对象风格
过程式风格
提交数据库连接的当前事务。
mysql
仅过程式风格:由 mysqli_connect() 或 mysqli_init() 返回的 mysqli 对象
flags
MYSQLI_TRANS_COR_*
常量的位掩码。
name
如果提供,则执行 COMMIT/*name*/
。
如果启用了 mysqli 错误报告 (MYSQLI_REPORT_ERROR
) 并且请求的操作失败,则会生成警告。此外,如果模式设置为 MYSQLI_REPORT_STRICT
,则会抛出 mysqli_sql_exception 而不是警告。
版本 | 描述 |
---|---|
8.0.0 |
name 现在可以为空。 |
参见 mysqli::begin_transaction() 示例。
注意:
此函数不适用于非事务型表类型(如 MyISAM 或 ISAM)。
请注意,调用 mysqli::commit() 不会自动将 mysqli::autocommit() 设置回 'true'。
这意味着任何跟随 mysqli::commit() 的查询将在您的脚本退出时回滚。
我从不推荐仅使用一个值变体的 ?,例如:$var = expression ? $var : other_value 或 $var = expression ? null : other_value,而 php 支持异常捕获,所以,使用它! :)
这是我对 lorenzo 帖子的意见
<?php
// 合并的变体
$mysqli->autocommit(FALSE);
try{
$mysqli->query("INSERT INTO myCity (id) VALUES (100)") or throw new Exception('error!');
// 或者我们可以使用
if( !$mysqli->query("INSERT INTO myCity (id) VALUES (200)"){
throw new Exception('error!');
}
}catch( Exception $e ){
$mysqli->rollback();
}
$mysqli->commit();
?>
这是一个解释 rollback 和 commit 函数强大功能的示例。
假设您希望确保所有查询在写入数据库之前都必须执行完毕且无错误。
以下代码:
<?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 VALUE
// 现在让我们测试我们的控制变量
$all_query_ok ? $mysqli->commit() : $mysqli->rollback();
$mysqli->close();
?>
希望对您有帮助!
这是为了澄清 Flags 参数及其含义
MYSQLI_TRANS_COR_AND_CHAIN
将 "AND CHAIN" 附加到 mysqli_commit 或 mysqli_rollback。
MYSQLI_TRANS_COR_AND_NO_CHAIN
将 "AND NO CHAIN" 附加到 mysqli_commit 或 mysqli_rollback。
MYSQLI_TRANS_COR_RELEASE
将 "RELEASE" 附加到 mysqli_commit 或 mysqli_rollback。
MYSQLI_TRANS_COR_NO_RELEASE
将 "NO RELEASE" 附加到 mysqli_commit 或 mysqli_rollback。
为了澄清这些选项
AND CHAIN 子句会导致在当前事务结束时立即开始新的事务,并且新事务与刚刚结束的事务具有相同的隔离级别。
RELEASE 子句会导致服务器在终止当前事务后断开当前客户端会话的连接。
当您要执行大量事务时,比如您要从循环中将项目插入到数据库,使用 mysqli_commit 会更好,因为它只会命中数据库一次。
// 错误的方法
示例 1
$con = mysqli_connect("host", "username", "password", "database") or die("Could not establish connection to database");
$users = ["chris", "james", "peter", "mark", "joe", "alice", "bob"]
for($i=0; $i<count($users); $i++){
$user= $users[$i];
$query = mysqli_query($con, "INSERT INTO users (username) VALUES ('$user') ");
}
//正确方法
示例 2
$con = mysqli_connect("host", "username", "password", "database") or die("Could not establish connection to database");
$users = ["chris", "james", "peter", "mark", "joe", "alice", "bob"]
//关闭自动提交
mysqli_autocommit($con, FALSE)
//执行一些事务
for($i=0; $i<count($users); $i++){
$user= $users[$i];
$query = mysqli_query($con, "INSERT INTO users (username) VALUES ('$user') ");
}
//对数据库进行一次性操作
mysqli_commit($con)
与示例 1 一样,由于列表中有 7 个项目,这意味着将对数据库进行 7 次操作,这会严重影响性能。但在示例 2 中,由于我们已经关闭了自动提交,这意味着事务将被排队,直到我们显式调用 mysqli_commit($con)
Lorenzo 代码的简洁性令人钦佩。
但是,最好也检查 $mysqli->affected_rows,以确保 INSERT 语句没有失败。
<?php
$result_query = @mysqli_query($query, $connect);
if (($result_query == false) &&
(mysqli_affected_rows($connect) == 0))
{
// 验证查询是否完全执行,并验证它
// 对表有影响
$success = false;
// 在这里,开发人员也可以选择添加一个回滚
// 语句
}
?>