tp5.1需手动扩展initconnect或监听异常实现断线重连,tp6支持配置'ping'=>true在获取连接时自动检测并丢弃失效连接,但两者均不支持事务中自动重连。

TP5.1 没有内置数据库断线重连机制,TP6 也未提供全自动重连能力,但两者在应对连接中断的策略设计、可干预点和实现方式上有本质差异。
TP5.1:完全依赖手动注入心跳与错误捕获
TP5.1 的数据库连接类(think\db\Connection)不包含 ping 或自动重连逻辑。一旦 MySQL 连接因超时(如 wait_timeout)断开,后续查询直接报错 SQLSTATE[HY000] [2006] MySQL server has gone away,框架不会尝试恢复。
- 必须在连接初始化后主动执行一次
SELECT 1检测,常见做法是继承think\db\Connection并重写initConnect()方法,在$this->connect()后立即调用$this->query('SELECT 1', [], false) - 也可通过全局监听
Db::listen(),捕获上述错误码后手动执行$this->close()+$this->connect() - 该方式属于“被动兜底”,无法预防连接失效,且需开发者自行保障重试时机与并发安全
TP6:支持配置化 ping 检测,但重连仍需手动触发
TP6 在数据库配置中新增了 ping 选项(默认关闭),启用后会在每次从连接池获取连接时执行一次 PING 命令。若检测失败,框架会自动丢弃该连接并尝试新建一个——这是 TP6 相比 TP5.1 的关键进步。
- 需在
config/database.php的连接配置中显式开启:'ping' => true - 该机制仅作用于连接复用场景(如 Swoole 长连接、连接池),对传统 FPM 每次请求新建连接的模式意义不大
- 即使启用 ping,框架也不会在查询执行中途自动重试 SQL;若查询过程中连接意外中断(如网络闪断),仍需像 TP5.1 那样靠异常捕获 + 手动重连
共同限制与注意事项
两者均不支持事务中的自动重连。一旦事务已开始(Db::transaction() 或模型事务),连接中断会导致事务状态不可控,必须回滚并由业务层决定是否重试整个事务流程。
- TP5.1 和 TP6 都无法在
INSERT/UPDATE执行一半时自动续上连接,强行重连会破坏 ACID - 使用 Swoole 或连接池时,务必确保连接对象的生命周期与请求隔离,避免前序请求的断连污染后续请求的连接上下文
- 真正稳定的长连接方案,需结合 MySQL 的
auto_reconnect=on(已废弃)、应用层心跳、连接池健康检查三者协同











