【发布时间】:2021-10-03 19:58:18
【问题描述】:
我有 3 个数据库,我需要创建数据库 A,然后创建数据库 B,然后创建链接数据库 A_B。
我在PHP中使用mysqli事务,有一个奇怪的情况(这是我第一次使用php事务),失败时它永远不会回滚,比如数据库A插入失败,但B仍然创建。和 A_B 创建不正确。
mysqli_begin_transaction($link);
try{
$sql = "INSERT INTO A (
....)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?,?);";
$stmt = mysqli_prepare($link,$sql);
mysqli_stmt_bind_param($stmt,"sssssssssssss",
....
);
mysqli_stmt_execute($stmt);
$param_new_A_Rec = mysqli_insert_id($link);
for($i = 0; $i < $tot; $i++){
$sql = "INSERT INTO B (..)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?);";
$stmt = mysqli_prepare($link,$sql);
mysqli_stmt_bind_param($stmt,"ssssssssssss",
...
);
mysqli_stmt_execute($stmt);
$param_new_B_Rec = mysqli_insert_id($link);
$sql = "INSERT INTO A_B (
param_new_A_Rec,
param_new_B_Rec,
....
(?,?,?,?,?,?);";
$stmt = mysqli_prepare($link,$sql);
mysqli_stmt_bind_param($stmt,"ssssss",
....
);
mysqli_stmt_execute($stmt);
}
mysqli_commit($link);
}catch (mysqli_sql_exception $exception) {
mysqli_rollback($link);
throw $exception;
}
为什么如果 A 失败了,它永远不会命中 rollback() 并且它创建了不正确的 A_B 和 B 数据?我在这里错过了什么吗? 任何帮助将不胜感激!
【问题讨论】:
-
嘿,事务来自数据库而不是 PHP,看来你没有遗漏什么,你可以检查一下: 1. 一些MySQL DB Engines 不支持事务,在链接中是doc,您可以在其中检查您正在使用的那个是否支持它。 2.任何与
mysqli_sql_exception无关的错误都不会触发rollback -
你好 Juan,引擎是 InnoDB。我有一个案例,当我将日期插入数据库 A 时,该字段是 tinyInt(),我按下“false”,它无法创建数据库 A,但它继续使用数据库 B 和数据库 A_B,外键链接不正确,这应该触发 mysqli_sql_exception 吗?
-
该引擎有支持,您尝试在
catch块中打印一些内容吗?看看它是否被捕获。 -
我错过了编辑。只是为了尝试,您可以将回滚放在不会产生影响的提交之前; false 作为数据类型可以被认为是
0,如果您在 AI 列中有以前的寄存器,mysqli_insert_id将返回一个有效的 id。 -
请告诉我们:是否会引发异常?您是否启用了例外?此代码是否在命名空间内?如果创建了 B 和 A_B,你怎么知道 A 失败?听起来好像 A 成功完成了,否则你会得到异常。
标签: php mysqli transactions commit rollback