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

MySQLi事务遇错误后savepoint全部丢失,无法回滚求助

MySQLi事务中错误查询导致保存点消失的原因及解决办法

这不是MySQLi的问题,本质是MySQL InnoDB存储引擎的事务默认行为。

核心原因

当事务中执行了一条产生语句级错误(比如你这里重复创建已存在的表)的SQL时,InnoDB不会立即终止整个事务,但会自动清除当前事务内所有已创建的保存点。此时事务进入"部分失败"状态,保存点机制不再可用,后续执行ROLLBACK TO SAVEPOINT自然会提示"保存点不存在"。

而你后续执行的commit()会提交事务中所有之前成功执行的语句,也就是三条INSERT操作,这就是最终三条数据都被提交的原因。

你的代码问题点

你在执行错误的CREATE TABLE语句后,没有检查SQL执行是否成功就继续执行回滚到保存点的操作,忽略了错误已经导致保存点失效的事实。

解决方案

执行每一条SQL后都必须检查错误,一旦发现错误,根据业务需求选择:

  • 直接回滚整个事务(放弃所有操作);
  • 若需要继续事务,此时已无保存点可用,只能继续执行后续语句或手动重新创建保存点(但不推荐,因为事务已处于部分失败状态)。

修改后的示例代码:

$mysqli = new mysqli($_HOST, $_USER, $_PASS, $_DB_NAME); // 替换为你的数据库凭证
$mysqli->begin_transaction();

$mysqli->savepoint("SP1");
if (!$mysqli->query("INSERT INTO Users (Username, FavouriteColour) VALUES ('Alice', 'Red');")) {
    $mysqli->rollback();
    die("插入Alice失败:" . $mysqli->error);
}

$mysqli->savepoint("SP2");
if (!$mysqli->query("INSERT INTO Users (Username, FavouriteColour) VALUES ('Bob', 'Green');")) {
    $mysqli->rollback();
    die("插入Bob失败:" . $mysqli->error);
}

$mysqli->savepoint("SP3");
if (!$mysqli->query("INSERT INTO Users (Username, FavouriteColour) VALUES ('Charlie', 'Blue');")) {
    $mysqli->rollback();
    die("插入Charlie失败:" . $mysqli->error);
}

// 执行错误语句时检查错误
if (!$mysqli->query("CREATE TABLE Users (ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY, Username VARCHAR(255), FavouriteColour VARCHAR(64));")) {
    // 发现错误,直接回滚整个事务
    $mysqli->rollback();
    die("建表失败:" . $mysqli->error);
}

// 若前面无错误,再执行回滚到保存点
if (!$mysqli->query("ROLLBACK TO SAVEPOINT SP2")) {
    $mysqli->rollback();
    die("回滚到SP2失败:" . $mysqli->error);
}

$mysqli->commit();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:07:39