CodeIgniter 3 不支持嵌套事务,需依赖 InnoDB 事务 + 手动顺序执行与异常拦截实现多表删除原子性:开启事务后,SQL 错误由 trans_complete() 自动回滚;PHP 异常须手动调用 trans_rollback();删除顺序须符合外键约束;所有操作需共用同一数据库连接。

CodeIgniter 3(CI3)本身不提供原生的嵌套事务支持,也没有内置的保存点(SAVEPOINT)机制。当需要在多张表之间执行删除操作并保证原子性时,必须依靠 MySQL InnoDB 的事务特性 + 手动控制流程来实现“异常时全部回滚”。关键不是“嵌套”,而是“统一事务上下文下的顺序执行与异常拦截”。
开启事务并确保自动回滚触发
CI3 的数据库类通过 $this->db->trans_start() 和 $this->db->trans_complete() 管理事务。只要中间任意一个查询失败(如主键不存在、外键约束、SQL 语法错误),CI3 会自动标记事务为失败,并在 trans_complete() 时执行 ROLLBACK。
- 无需手动写
ROLLBACK语句,CI3 底层已封装 - 必须使用 InnoDB 引擎,MyISAM 不支持事务
- 所有操作(DELETE A、DELETE B、DELETE C 关联)必须在同一个数据库连接实例中执行
多表删除顺序与外键约束处理
删除顺序必须符合外键依赖关系,否则会因约束失败直接中断——这不是业务逻辑错误,而是数据库强制拦截。例如:先删子模块(B 表)、再删关联关系(C 表中的记录)、最后删导航主表(A 表)。
- 若 B 表有外键指向 A 表,就不能先删 A;应先删 B,再删 A
- C 表是 B 和另一张表(如 device_type)的中间表,需在 B 删除后、或与 B 同步清理
- 可在模型方法中按依赖顺序组织 SQL,避免“删不掉”的硬性报错
捕获 PHP 层异常并强制回滚
CI3 的事务机制对 SQL 错误敏感,但对 PHP 运行时异常(如空数组、类型错误、自定义校验失败)不自动响应。如果逻辑判断出错(比如查不到子模块列表就抛异常),需主动干预事务状态。
- 在
try块中执行业务逻辑,一旦 throw Exception,立即调用$this->db->trans_rollback() - 不要只依赖
trans_complete()—— 它只管 SQL 执行结果,不管 PHP 异常 - 示例片段:
避免事务失效的常见坑
CI3 事务容易“看似开启实则无效”,尤其在多模型调用或加载不同数据库组时。
- 所有模型必须共享同一个数据库连接对象(默认即可,勿在模型里重新
$this->load->database()) - 不要在事务块内做 redirect、exit 或 die,会导致
trans_complete()无法执行 - 事务期间避免调用非事务安全的操作,如文件写入、cURL 请求失败不处理等——它们不影响 DB 回滚,但会让业务状态失衡
- 调试时可加
echo $this->db->last_query();查看每条 SQL 是否真正在事务中执行

















