mysql事务回滚核心是php显式控制:开启→执行→成功commit、失败rollback;mysql本身不支持try-catch,innodb引擎才有效,myisam下rollback静默失效,须禁用autocommit并避免ddl隐式提交。

PHP 8 中使用 MySQL 事务回滚,核心是**显式控制事务生命周期**:开启 → 执行 → 成功则提交,失败则回滚。MySQL 本身不支持 try-catch,所以回滚必须由 PHP 主动触发,不能依赖数据库自动处理。
确保环境支持事务
事务只在 InnoDB 引擎下有效,MyISAM 不支持回滚(调用 rollback 也静默失败)。检查方式:
- 建表时指定 ENGINE=InnoDB,例如:
CREATE TABLE users (...) ENGINE=InnoDB; - 运行
SHOW ENGINES;,确认InnoDB行的SUPPORT列为YES - 避免在事务中执行
CREATE TABLE、ALTER TABLE、TRUNCATE等隐式提交语句
推荐写法:PDO + 异常模式(最安全)
PDO 配合 PDO::ERRMODE_EXCEPTION 能自动抛异常,让 catch 块天然成为回滚入口:
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
<pre class="brush:php;toolbar:false;">$pdo->beginTransaction();
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
// 模拟业务校验失败
$balance = $pdo->query("SELECT balance FROM accounts WHERE id = 1")->fetch()['balance'];
if ($balance commit();
echo "转账成功";} catch (Exception $e) { $pdo->rollback(); echo "操作失败,已回滚:" . $e->getMessage(); }
备选写法:mysqli 面向对象风格
若用 mysqli,需手动检查每条语句返回值,并显式调用 rollback():
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
<p>// 关闭自动提交(关键!)
$mysqli->autocommit(false);</p><p>if (
$mysqli->query("INSERT INTO logs(msg) VALUES ('start')") &&
$mysqli->query("UPDATE inventory SET qty = qty - 1 WHERE item = 'book'") &&
$mysqli->query("INSERT INTO orders(user_id) VALUES (123)")
) {
$mysqli->commit();
echo "全部成功";
} else {
$mysqli->rollback();
echo "某步失败,已回滚:" . $mysqli->error;
}</p><p>// 恢复自动提交(可选,便于后续非事务操作)
$mysqli->autocommit(true);</p>
常见失效原因与避坑点
- 忘记关闭 autocommit:默认是开启的,不关就等于每条 SQL 自动提交,rollback 无效
- 用了 MyISAM 表:rollback 不报错但也不起作用,务必确认引擎类型
-
事务中途执行了 DDL:如
CREATE TEMPORARY TABLE会隐式提交,导致前面修改无法回滚 - 异常未被捕获或 rollback 调用被跳过:比如在 if-else 中只写了 commit,漏了 else 里的 rollback
- 连接断开或超时:事务自动终止,但程序可能没感知,建议加连接健康检查
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











