PDO连接创建后必须显式关闭自动提交,最稳妥方式是调用beginTransaction(),它自动关闭autocommit并创建事务上下文,兼容主流驱动;若已处于事务中则返回false,需检查errorInfo()。

PDO 连接创建后必须显式关闭自动提交,PHP 8.5.5 不会自动改掉这个行为
pdo::beginTransaction() 是最稳妥的关闭方式
调用 beginTransaction() 不仅开启事务,还会自动把 PDO::ATTR_AUTOCOMMIT 设为 false,兼容性好、无需额外判断。
- 它在 MySQL、PostgreSQL、SQLite 等主流驱动下都有效
- 如果连接已处于事务中(比如之前没 commit 就断开了),
beginTransaction()会失败并返回false,这时该查errorInfo() - 不要在
beginTransaction()之后再调setAttribute(PDO::ATTR_AUTOCOMMIT, false)——无效,PDO 已锁死该状态
mysqli 需要两步:先关 autocommit,再 start transaction
mysqli 没有封装好的事务启动方法,autocommit(false) 是前提,否则 begin_transaction() 或 START TRANSACTION 都只是“形式上”开事务,SQL 仍会立即生效。
- 必须先调
$mysqli->autocommit(false),检查返回值是否为true - 再调
$mysqli->begin_transaction()(PHP 7.0+)或执行START TRANSACTION,增强语义明确性 - 事务结束后务必恢复:
$mysqli->autocommit(true),否则复用连接时后续查询全卡住
setAttribute(PDO::ATTR_AUTOCOMMIT, false) 的陷阱
这个方法只在连接刚建好、还没开启事务时有效;一旦 beginTransaction() 被调过,再设这个属性就完全不起作用。
立即学习“PHP免费学习笔记(深入)”;
- 如果你用它关了 autocommit,但忘了调
beginTransaction(),后续commit()会报 “There is no active transaction” - 它不触发事务上下文,所有 SQL 还是单条执行,只是不自动提交——容易误以为进了事务
- PHP 8.5.5 下该行为与旧版本一致,没有变更,别指望配置文件或 php.ini 能绕过代码控制
phpMyAdmin 里 SET autocommit=0 为什么总失效
phpEnv 自带的 phpMyAdmin 默认每条 SQL 单独执行一个新会话,SET autocommit = 0 只影响当前语句所在会话,下一条就重置了。
- 验证是否真关掉:
SELECT @@autocommit,看到结果是0才算成功 - 可靠做法:用界面顶部的「启用自动提交」开关(勾掉),或整段写成
START TRANSACTION; ... ; COMMIT;放在同一个执行框里 - DDL 语句(如
CREATE TABLE)会隐式提交,哪怕你在事务里执行,也会立刻中断当前事务
事务不是开关一按就完事的事——PDO 关了 autocommit 后不会自动恢复,mysqli 忘了 autocommit(true) 会让后续请求集体挂起。最容易被忽略的是:长连接池(比如 PHP-FPM 持久连接)里残留的未结束事务,可能拖垮整个服务。



















