Laravel 不自动重连 MySQL,需手动配置 PDO 选项并调用 DB::purge() + DB::reconnect() 清除失效连接;重试仅对 SQLSTATE[2013]/[2006] 有效,且应避免在事务或模型事件中调用。
MySQL 连接超时后 Laravel 不自动重连?
和
都不管用
默认情况下,Laravel 不会在查询失败时自动重试连接。哪怕你设置了
里的
,它也只是抛异常,不会重连。真正触发重连的时机,是下一次请求到来、连接被检测为“断开”时——但这个检测本身依赖于
或底层驱动的健康检查逻辑,而默认配置里压根没开。
必须手动在
的 MySQL 配置中添加
,否则连接异常会被静默吞掉
启用重连需显式设置
(部分版本兼容需要),否则预处理语句可能卡死连接
更关键的是加
,让底层 PDO 在握手阶段就超时,避免挂起等待
不要指望
被自动调用;它只在你手动调用或某些中间件里才生效,不是兜底机制
Laravel 9+ 中如何配置连接池级重试次数?
和
不是数据库配置项
和
是队列任务的配置,和数据库连接完全无关。数据库层的重试必须靠封装逻辑或扩展连接器实现,不能靠 config 文件一键开启。
真正的重试控制点在
类的
方法里,但它不暴露重试参数
若想在连接建立失败时重试,得自己写一个继承自
的类,并重写
,用
循环 +
包裹
注意:重试不能无脑循环,要配合
(100ms)避免雪崩,且最多 3 次——再多次大概率是网络或 DB 问题,不是临时抖动
别在
内部做重试,事务上下文里重连会导致
无法恢复
为什么
报
后,后续查询仍失败?
因为 Laravel 的连接对象是单例缓存的,
返回的是已失效的 PDO 实例指针,不是新连接。即使你 catch 到异常并调用
,也只重置了连接器内部状态,未刷新当前连接实例上的 PDO 对象。
Laravel 13.2.0
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
下载
最稳妥做法是:捕获
或
后,立即执行
清除连接缓存,再调用
如果用了读写分离,记得对
和
分别 purge,否则只清主库连接,从库仍报错
不要在模型的
或
事件里做 reconnect —— 此时连接尚未初始化,会触发
测试时用
模拟断连比改 timeout 更真实,避免误判重试逻辑是否生效
生产环境要不要开连接重试?
日志里频繁出现
要看错误类型。如果是
,说明 Laravel 根本连不上 MySQL 进程,重试只是把失败延迟几秒;如果是
,才是典型的网络抖动或 wait_timeout 触发,这时重试才有意义。
线上建议只对
和
错误码做重试,其他一律快速失败,避免掩盖真实部署问题
用
记录所有慢查询和连接异常,但别在监听回调里做重试操作——它运行在查询生命周期内,干扰执行流
连接池大小(
)比重试更重要;连接不够用时,重试只会加剧排队
真正容易被忽略的是 MySQL 的
和 Laravel 的
是否匹配;设成 60 秒却让连接池 idle 120 秒,必然断连,重试解决不了根本
PDO::ATTR_ERRMODEDB::reconnect()optionsPDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTIONDB::reconnect()config/database.php'options' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]'options' => [PDO::ATTR_EMULATE_PREPARES => true]'options' => [PDO::ATTR_TIMEOUT => 5]DB::reconnect()retry_afterretry_timesretry_afterretry_timesIlluminate\Database\Connectors\MySqlConnectorconnect()MySqlConnectorconnect()fortry/catchparent::connect()usleep(100000)DB::transaction()SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayDB::connection()->getPdo()Connection refusedgetPdo()DB::reconnect()Illuminate\Database\QueryExceptionPDOExceptionDB::purge('mysql')DB::reconnect()'read''write'boot()creatingInvalidArgumentException: Database connection [xxx] not configured.tcpkill -i lo port 3306DB::listen()SQLSTATE[HY000] [2002] Connection refused[2002] Connection refused[2013] Lost connection to MySQL server during query[2013][2006]DB::listen()'pool' => ['min_connections' => 5, 'max_connections' => 20]wait_timeoutlifetime