thinkphp 8.0 事务回滚失败主因是异常未穿透、连接不统一或表引擎非 innodb;必须确保闭包内异常穿透、所有操作共用同一 db 连接、目标表为 innodb 引擎,否则 rollback 形同虚设。

ThinkPHP 8.0 中调用 Db::rollback() 却发现数据没撤回,或 Db::transaction() 包裹的代码抛了 Exception 却仍提交成功,这类问题不是框架“坏了”,而是事务控制链在某个环节被意外切断——异常没穿透、连接不统一、引擎不支持,三者占其一,回滚就形同虚设。
确认表引擎是否为 InnoDB
执行 SHOW CREATE TABLE user; 查看建表语句末尾的 ENGINE=xxx;如果不是 【ENGINE=InnoDB】,事务根本不会生效,ROLLBACK 会静默失败,数据已写入磁盘。
MyISAM、MEMORY 等引擎不支持事务,ThinkPHP 不校验也不报错,只管发 SQL,MySQL 直接忽略 ROLLBACK 指令。
修复必须执行:ALTER TABLE user ENGINE=InnoDB;,操作前务必先备份整表。
Db::transaction() 闭包内异常未穿透
方法一:直接移除闭包内的 try-catch
❌ 错误写法(事务不回滚):
Db::transaction(function () {<br> try {<br> Db::name('order')->insert([]);<br> } catch (\Exception $e) {<br> Log::error($e);<br> // 异常被吞掉,框架收不到,事务照常 commit<br> }<br>});
✅ 正确写法(让异常自然冒泡):
Db::transaction(function () {<br> Db::name('order')->insert([]);<br> Db::name('log')->insert(['action' => 'create']);<br>});
这一步操作起来很简单,只要闭包里不加任何 try-catch,异常就能穿透到 Db::transaction() 内部捕获层,自动触发 rollback。
手动事务中 commit/rollback 未配对
第一步:调用 Db::startTrans();
第二步:在 try 块中执行全部数据库操作
第三步:成功后调用 Db::commit();
第四步:catch 中必须调用 Db::rollback();,且不能遗漏
⚠️ 注意:如果只写了 startTrans 和 commit,但没写 rollback,或 catch 块为空,异常发生后事务状态将悬空——连接持续处于 active transaction 状态,后续同连接查询可能被锁住,甚至因超时被 MySQL 自动回滚却无日志提示。
第五步:绝不依赖 finally 块做 commit/rollback 判断——finally 无法知道该提交还是回滚,必须由 try/catch 显式分流。
跨模型操作导致连接隔离
在事务中混用 UserModel::create() 和 Db::table('log')->insert(),很可能一个成功一个失败却不回滚,原因很直接:【模型默认使用独立 PDO 连接实例】,而 Db::transaction() 只作用于当前 Db 门面绑定的那个连接。
解决方式只有一种:全部操作统一走 Db 类,例如都用 Db::name('user')->insert() 和 Db::name('log')->insert();若必须用模型,需显式复用连接:$userModel->db()->transaction(function () use ($userModel) { ... });
不要指望模型 save() 后能立刻用 Db::table() 查到数据——它们大概率不在同一个事务上下文里。
PHP 8.0+ 中 \Error 未被捕获
方法一:改用 \Throwable 兜底
try {<br> Db::startTrans();<br> // 业务逻辑<br> Db::commit();<br>} catch (\Throwable $e) {<br> Db::rollback();<br> throw $e;<br>}
方法二:避免在事务内触发致命错误
比如调用不存在的函数、内存溢出、require 失败等,这些属于 \Error 子类,\Exception 捕获不到,事务会卡在 active 状态,后续请求可能阻塞。
Db::transaction() 内部只捕获 \Exception,不捕获 \Error;PHP 8.0+ 的 TypeError、ParseError 都是 \Error,静默绕过回滚逻辑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











