codeigniter 3 不支持直接配置 autocommit,其事务控制依赖 trans_start()/trans_complete() 成对调用,默认由底层驱动决定 autocommit 状态;手动修改连接关闭 autocommit 不推荐,且 database.php 中添加 autocommit 配置无效。

CodeIgniter 3 中如何控制事务自动提交(autocommit)
CodeIgniter 3 的数据库类本身不暴露 autocommit 开关,它默认依赖底层 PDO 或 MySQLi 驱动的连接行为。MySQL 默认开启 autocommit,这意味着每条 INSERT/UPDATE/DELETE 语句都会立即生效——除非你显式调用 trans_start() 启动事务。
所以「配置自动提交」在 CI3 里实际是「确保事务块被正确包裹」,而不是改某个配置项。常见错误是只调用 trans_start() 却忘了 trans_complete(),导致后续查询仍处于事务中或连接状态异常。
-
trans_start()必须成对出现trans_complete(),否则事务不会真正提交或回滚 - 若使用
$this->db->trans_strict(TRUE),任何查询失败都会触发自动回滚,但需确保所有操作都在同一事务块内 - 不要在事务中混用原生
mysqli_query($this->db->conn_id, '...'),它绕过 CI 的事务管理,可能造成不一致 - CI3 不支持通过
database.php设置autocommit=FALSE;如需强制关闭,得手动修改底层连接(不推荐)
CodeIgniter 4 中事务与 autocommit 的真实控制点
CI4 的 Connection 类更透明,autocommit 状态由底层驱动决定,但你可以通过 startTransaction() / commit() / rollback() 显式干预。关键点在于:CI4 默认在每次 query() 前检查并启用 autocommit(如果已关闭),所以你不能靠“全局关 autocommit”来实现事务控制。
真正起作用的是这三步:
- 调用
$db->startTransaction()→ 底层执行SET autocommit = 0(仅当当前为 1 时) - 执行你的多条 DB 操作(
insert()、update()等) - 必须显式调用
$db->commit()或$db->rollback()→ 此时才恢复 autocommit 状态
遗漏 commit() 或 rollback() 会导致连接残留为 autocommit=0,下一次请求复用该连接时,所有写操作都卡在未提交状态——这是生产环境最隐蔽的锁表源头之一。
为什么不能在 database.php 里配 autocommit
CI3 和 CI4 的 database.php 配置数组中,没有 autocommit 这个键。你可能会看到 'pconnect' => FALSE 或 'char_set' => 'utf8',但它们和事务提交行为无关。试图添加 'autocommit' => FALSE 到配置里完全无效——框架压根不读这个字段。
如果你看到某些博客写了类似配置,那大概率是混淆了原生 PDO 的 DSN 参数(如 mysql:dbname=test;autocommit=0)和 CI 的封装逻辑。CI 的连接初始化过程会忽略这类自定义 DSN 行为,或在连接建立后立刻覆盖它。
事务失败后连接状态容易被忽略
最常被跳过的检查点是:事务失败后,连接是否还可用?比如在 CI3 中,trans_complete() 执行失败(如网络中断、超时),$this->db->trans_status() 返回 FALSE,但连接本身可能已断开或处于不可预测状态。此时若继续用 $this->db 查询,可能报错 MySQL server has gone away 或静默失败。
安全做法是:事务结束后,无论成功与否,都应检查 $this->db->trans_status();若为 FALSE,建议主动 $this->db->close() 并让下次请求重建新连接——尤其在长生命周期的 CLI 脚本或队列任务中。











