You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现4个mysqli查询任意失败时取消所有数据插入

解决多插入语句的原子性问题

嘿,你遇到的这个问题正好是数据库事务要解决的核心场景——我们需要让这4条插入操作成为一个原子单元:要么全部成功写入数据库,要么有任何一条失败就全部撤销,不会留下部分插入的数据。

为什么当前代码会出问题?

MySQL默认是「自动提交」模式,每执行一条INSERT语句,数据库就会立刻把数据持久化到磁盘。所以如果前两条成功了,第三条失败,前两条的数据已经留在库里了,没法撤销。

解决方案:使用数据库事务

我们可以通过手动控制事务来实现原子性,步骤如下:

  1. 关闭自动提交模式
  2. 开启事务
  3. 依次执行所有插入语句,逐个检查执行结果
  4. 如果所有语句都成功,就提交事务(把所有修改持久化)
  5. 如果任何一条失败,就回滚事务(撤销所有已经执行的修改)

修改后的代码示例

// 先关闭自动提交
mysqli_autocommit($connection, false);

// 标记是否所有操作都成功
$all_success = true;

// 执行第一条插入,检查结果
$datastok = mysqli_query($connection,"INSERT into stok (Kod_Barang, Kod_Rak, Harga, Tarikh_Jual) VALUES ('$Kod_Barang','$Kod_Rak','$Harga','$Tarikh_Jual')");
if (!$datastok) {
    echo "Stok插入失败: " . mysqli_error($connection);
    $all_success = false;
}

// 前面成功才继续执行后续语句
if ($all_success) {
    $databarang = mysqli_query($connection,"INSERT into barang (Kod_Barang, Nama_Barang, Bil_Barang) VALUES ('$Kod_Barang','$Nama_Barang','$Bil_Barang')");
    if (!$databarang) {
        echo "Barang插入失败: " . mysqli_error($connection);
        $all_success = false;
    }
}

if ($all_success) {
    $datalokasi = mysqli_query($connection,"INSERT into lokasi (Kod_Rak, Jenis_Barang) VALUES ('$Kod_Rak', '$Jenis_Barang')");
    if (!$datalokasi) {
        echo "Lokasi插入失败: " . mysqli_error($connection);
        $all_success = false;
    }
}

if ($all_success) {
    $datatarikh = mysqli_query($connection,"INSERT into tarikh (Nama_Barang, Tarikh_Beli) VALUES ('$Nama_Barang', '$Tarikh_Beli')");
    if (!$datatarikh) {
        echo "Tarikh插入失败: " . mysqli_error($connection);
        $all_success = false;
    }
}

// 根据结果提交或回滚
if ($all_success) {
    mysqli_commit($connection);
    echo "所有数据插入成功!";
} else {
    mysqli_rollback($connection);
    echo "插入失败,已撤销所有操作!";
}

// 恢复自动提交(可选,根据后续业务逻辑调整)
mysqli_autocommit($connection, true);

重要注意事项

  • 存储引擎支持:你的表必须使用InnoDB存储引擎(MySQL默认是这个,但老项目可能用不支持事务的MyISAM),可以用SHOW CREATE TABLE stok;命令查看表的存储引擎。
  • SQL注入风险:当前代码直接把用户输入拼接到SQL语句里,存在严重的SQL注入漏洞!建议改用预处理语句,示例如下(以第一条插入为例):
$stmt = mysqli_prepare($connection, "INSERT into stok (Kod_Barang, Kod_Rak, Harga, Tarikh_Jual) VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, "ssds", $Kod_Barang, $Kod_Rak, $Harga, $Tarikh_Jual);
$datastok = mysqli_stmt_execute($stmt);
  • 错误处理:不要用or die(),因为它会直接终止脚本,导致无法执行回滚操作,一定要手动判断每个语句的返回值。

内容的提问来源于stack exchange,提问作者MichaelSWS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:44:01