【MYSQL数据库异常处理】执行SQL语句报超时异常

MYSQL执行SQL语句异常:The last packet successfully received from the server was 100,107 milliseconds ago. The last packet sent successfully to the server was 100,101 milliseconds ago.

这个错误表明 MySQL 服务器与 JDBC 连接之间的通信超时了。通常由以下几种情况引起:

错误原因

长时间没有交互(MySQL 服务器关闭了空闲连接)

MySQL 服务器的 wait_timeout 或 interactive_timeout 设置较短,导致长时间未使用的连接被关闭。

SQL 查询执行时间过长

如果查询运行时间超过 JDBC 连接的 socketTimeout,MySQL 驱动程序会终止连接。

网络问题

服务器端或客户端的网络连接中断,导致 JDBC 连接失败。

MySQL 服务器崩溃或重启

服务器重启后,原来的连接失效,导致客户端报错。

解决方案

✅ 方法 1:增加 MySQL wait_timeout 和 interactive_timeout

执行以下 SQL 命令,查看 MySQL 服务器的超时时间:

sql 复制代码
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';

如果值较小(例如 28800 秒以下),可以尝试增加:

sql 复制代码
SET GLOBAL wait_timeout = 28800;
SET GLOBAL interactive_timeout = 28800;

⚠️ 注意:此修改对现有连接无效,仅对新连接生效。如果需要持久生效,请修改 my.cnf 或 my.ini 配置:

bash 复制代码
[mysqld]
wait_timeout=28800
interactive_timeout=28800

然后重启 MySQL 服务器。

✅ 方法 2:在 JDBC 连接 URL 中添加 autoReconnect=true&socketTimeout

修改 JDBC 连接 URL,设置自动重连和超时:

java 复制代码
String url = "jdbc:mysql://localhost:3306/testdb?autoReconnect=true&socketTimeout=60000";
Connection conn = DriverManager.getConnection(url, user, password);

autoReconnect=true:当连接丢失时,自动重新连接(⚠️ MySQL 8+ 已不推荐使用)。

socketTimeout=60000:设置 socket 超时时间为 60 秒,防止过早断开。

✅ 方法 3:使用 keep-alive 保持连接

如果 MySQL 连接长时间空闲,MySQL 服务器可能会断开连接。可以使用 HikariCP 或 Druid 连接池,每隔一段时间发送 ping 保持连接。

HikariCP 连接池配置
java 复制代码
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/testdb");
config.setUsername("root");
config.setPassword("password");
config.setMaximumPoolSize(10);
config.setMinimumIdle(2);
config.setIdleTimeout(30000);  // 30 秒空闲超时
config.setKeepaliveTime(15000); // 每 15 秒发送 keep-alive
HikariDataSource dataSource = new HikariDataSource(config);

keepaliveTime=15000:每 15 秒发送一个 ping,防止连接超时。

Druid 连接池配置
java 复制代码
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/testdb");
dataSource.setUsername("root");
dataSource.setPassword("password");
dataSource.setMinIdle(5);
dataSource.setMaxActive(10);
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestWhileIdle(true);
dataSource.setTimeBetweenEvictionRunsMillis(30000); // 30 秒检测一次

validationQuery="SELECT 1":连接池在连接空闲时,发送 SELECT 1 测试连接是否可用。

✅ 方法 4:检查 MySQL 服务器状态

如果服务器已经重启或崩溃,尝试重启 MySQL:

bash 复制代码
sudo systemctl restart mysql  # Linux
net stop mysql && net start mysql  # Windows

总结

还可以结合 连接池 + socketTimeout + keepalive 方式,来确保 JDBC 连接的稳定性。

相关推荐
for_ever_love__4 分钟前
LangChain Text-to-SQL:让不会写 SQL 的人查数据库
数据库·sql·langchain·大模型·agent·rag·问答
梦想不只是梦与想17 分钟前
SQLAlchemy:查询与操作 (三)
数据库·python·sqlalchemy
Aric_Jones25 分钟前
WAL / CDC / 复制槽 /位点
数据库·oracle
草莓熊Lotso35 分钟前
【C++ 基于微服务的即时通讯系统】基建三件套:gflags + gtest + spdlog 源码编译安装与实战入门
linux·网络·数据库·c++·微服务·log4j
bksczm39 分钟前
Redis基础篇之初识分布式
数据库·redis·分布式
for_ever_love__1 小时前
MySQL 索引类型全解:B+Tree / Hash / R-Tree / 全文 的底层差异,以及一次性建对的选型表
数据库·mysql·b+树·唯一索引·全文索引·索引类型·索引分类
仍然.9 小时前
Redis---缓存
数据库·redis·缓存
Aloudata9 小时前
LookML 语义模型 vs 企业级独立语义层:BI 建模语言能否承担企业语义底座?
数据库·人工智能·数据分析·数据资产·dataagent
细嗅蔷薇@9 小时前
排序和分⻚(order by 、limit)
数据库·oracle
wdfk_prog9 小时前
LWIP教程 09:从 `tcp_slowtmr()` 到 Fast Retransmit——TCP 超时重传与重复 ACK
服务器·网络·数据库·网络协议·tcp/ip