TP6的break_reconnect=>true仅在PDO异常且ERRMODE设为EXCEPTION时生效,常见失效因未设ERRMODE、事务中断、Swoole/CLI绕过、配置位置错误;initConnect(false)不检测连接,推荐before_execute中用getAttribute校验;deploy=>1启用连接复用,CLI需主动close;事务中断后须外层重试。

TP6 默认不自动重连,break_reconnect 开关只在特定条件下生效,盲目开启可能掩盖真实问题。
为什么 break_reconnect => true 有时没用?
这个配置不是“万能重连开关”,它只在 PDO 抛出异常(如 SQLSTATE[HY000] [2006] MySQL server has gone away)且 PDO::ATTR_ERRMODE 已设为 PDO::ERRMODE_EXCEPTION 时触发。常见失效原因:
-
params里没显式设置PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,导致错误被静默忽略 - 事务中发生断连:TP6 不会在事务失败后重试,而是直接
rollback并抛出异常 - 用了 Swoole 或 CLI 长任务:连接池复用下,
break_reconnect可能被绕过,因为连接对象还“活着”但底层已断 - 配置写在了错误位置:必须放在具体数据库连接配置块内(如
connections.mysql),而非顶层或default键下
手动探测连接有效性比 SELECT 1 更轻量
TP6 的 initConnect(false) 不检测连接存活,靠发一次 SELECT 1 成本高、易进慢日志。更稳妥的做法是调用 PDO::getAttribute(PDO::ATTR_SERVER_INFO) —— 它不走 SQL 解析器,只触发连接层心跳。
推荐在 Db::event('before_execute') 中插入校验逻辑:
立即学习“PHP免费学习笔记(深入)”;
Db::event('before_execute', function ($connection) {
try {
$pdo = $connection->getPDO();
$pdo->getAttribute(PDO::ATTR_SERVER_INFO);
} catch (\PDOException $e) {
if (strpos($e->getMessage(), 'MySQL server has gone away') !== false) {
$connection->close();
$connection->initConnect(true);
}
}
});
注意:不要在模型基类的 initialize() 里做这事,它只在模型首次加载时执行一次,无法覆盖后续查询。
deploy => 1 是连接复用关键,不是“长连接”噱头
TP6 不支持原生 PDO 持久连接(PDO::ATTR_PERSISTENT 基本无效),真正起作用的是框架级连接池。启用 deploy => 1 后,同配置的请求会复用已有 PDO 实例,配合 pool_size 和 MySQL 的 max_connections 才能压住连接数暴涨。
- 不配
deploy => 1,哪怕break_reconnect => true开着,每次重连都新建 PDO,Too many connections很快出现 - CLI 队列消费场景(如
queue:work)必须主动$connection->close(),否则 while 循环里连接越积越多 -
pool_time参数控制空闲连接存活时间,默认不清理,高并发下容易堆积旧连接
事务内重连必须重开事务,不能复用上下文
事务一旦因连接中断 rollback,当前 Connection 对象就处于不可用状态。此时即使重连成功,再调用 Db::transaction() 也会报 There is no active transaction。
正确做法是把重试逻辑包在外层,每次失败后重新进入事务:
for ($i = 0; $i < 3; $i++) {
try {
Db::transaction(function () {
Db::table('order')->where('id', 123)->update(['status' => 'paid']);
});
break;
} catch (\think\db\exception\PDOException $e) {
if ($i === 2) throw $e;
usleep(100000);
}
}
复杂点在于:重试次数、间隔、是否告警得按业务定——支付回调可以试 3 次,秒杀库存扣减试 1 次就得熔断,别指望框架替你做决策。



















