队列进程崩溃前数据库已断开,db::connect() 不会自动重连;需在 handle() 中调用 ping() 或封装重试函数。任务丢失因进程异常终止导致状态未更新,应配置 ttr 和 maxtries 并启用失败日志。事务内 dispatch 队列任务会复用连接引发死锁,须使用独立连接。pdo 错误被吞需显式捕获并记录 sqlstate。

队列进程崩溃前数据库已断开,Db::connect() 不会自动重连
ThinkPHP 的队列消费者(如 php think queue:work)是长生命周期进程,MySQL 连接空闲超时(默认 8 小时)后会被服务端主动断开,但 TP 默认不会在下次查询前检测连接有效性。结果就是下一次 Db::table()->select() 直接抛出 PDOException: MySQL server has gone away,进程退出,任务卡住。
解决不是靠“重连配置”,而是让每次查询前强制验证连接状态:
- 在队列任务的
handle()开头加Db::connection()->ping();,失败则抛异常由队列框架重试 - 或全局替换连接类:继承
think\db\Connection,重写initConnect(),在connect()后调用$this->getPDO()->getAttribute(PDO::ATTR_CONNECTION_STATUS)检查(注意 PHP 8.1+ 才支持该属性) - 更稳妥的做法是:把数据库操作封装进带重试的函数里,比如
retryQuery(fn() => Db::table('log')->insert($data)),重试间隔 100ms,最多 3 次
queue:work 进程被 kill 或 OOM 时,未完成任务直接丢失
TP 默认使用数据库驱动队列,任务执行中若进程意外终止(如服务器重启、内存溢出、手动 kill -9),status 字段仍为 0(等待中),但实际已无消费者处理——这不是断连问题,是任务状态未及时更新。
必须启用「任务过期」和「失败重试」双保险:
- 配置
queue.default.ttr(time to run)为合理值(如 300 秒),超过该时间未完成则标记为失败 - 设置
queue.default.maxTries≥ 3,失败后自动重新入队(注意幂等性) - 在
config/queue.php中开启'failed' => ['driver' => 'database'],否则失败任务不落库,无法排查
事务内执行队列任务,连接复用导致死锁或超时
常见错误是在控制器事务里 dispatch 一个队列任务,然后等它完成——这会让队列任务复用同一个数据库连接句柄,而主事务未提交前,连接被占住,队列任务一查库就卡死。
根本原则:队列任务必须使用独立连接,不能继承父进程上下文:
- 禁止在
Db::transaction()内 dispatch 后同步等待结果;应改为异步通知(如 Redis Pub/Sub 或回调 URL) - 在队列任务
handle()中显式指定连接:Db::connect('mysql2')->table('xxx')->insert(...),避免复用默认连接 - 如果必须共享事务语义,改用消息表 + 定时扫描模式,而不是依赖队列中间件的原子性
日志里看不到 PDO 错误,try/catch 捕不到 SQLSTATE[HY000]
TP 默认把 PDO 异常转成 think\Exception,但队列框架(如 topthink/think-queue)在捕获异常时可能只打印 getMessage(),而关键的 SQLSTATE 和错误码被吞掉,导致无法区分是连接断开、唯一键冲突还是语法错误。
要暴露真实错误细节:
- 在队列任务里用
try { ... } catch (\PDOException $e) { \think\facade\Log::error('DB error: '.$e->getMessage().' | Code:'.$e->getCode().' | SQLSTATE:'.$e->getSQLState()); } - 确保
config/database.php中'deploy' => 0(非分布式部署),否则部分错误上下文会被清空 - 不要依赖
Db::getLastSql(),它在异常发生后可能为空;改用$e->getTraceAsString()定位具体哪行 SQL 出问题
连接断开不是孤立问题,它总和任务状态管理、异常传播路径、连接生命周期混在一起。最容易被忽略的是:你写的 catch 可能根本没机会执行,因为队列框架在底层就 exit() 了——所以务必配好 maxTries 和 ttr,让系统自己兜底,而不是指望单次执行完美。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











