🧱 一、背景:建立连接后,客户端与数据库的交互流程
在 Java 应用中访问数据库时,整个过程可以分为以下几个阶段:
+-------------------+
| 客户端发起请求 |
+-------------------+
↓
+-------------------+
| 1. connectTimeout |
| 建立 TCP 连接 |
+-------------------+
↓
+-------------------+
| 2. queryTimeout |
| 数据库执行 SQL |
+-------------------+
↓
+-------------------+
| 3. socketTimeout / readTimeout |
| 等待数据库返回结果 |
+-------------------+
↓
+-------------------+
| 返回结果或异常 |
+-------------------+
📌 二、什么是 socketTimeout
或 readTimeout
?
✅ 定义:
socketTimeout
(或称readTimeout
)是指:在已经成功建立数据库连接的前提下,客户端等待数据库返回数据的最大时间。
如果在这段时间内没有收到任何数据,则抛出超时异常。
🔍 三、等待数据库返回的“结果”到底是什么?
当你发送一条 SQL 到数据库之后,数据库会进行以下操作:
- 解析 SQL 语句;
- 执行查询/更新操作;
- 将结果集封装并返回给客户端。
而 socketTimeout
就是用于控制第 3 步——客户端等待数据库“把结果传回来”的时间。
🧾 举个例子:
SELECT * FROM users WHERE create_time > '2024-01-01';
数据库做了什么?
- 执行完 SQL;
- 开始准备返回数据(可能几万条);
- 分批次通过网络传输到客户端;
客户端在做什么?
- 接收数据库返回的数据包;
- 组装成
ResultSet
; - 你调用
rs.next()
获取每一行;
在这个过程中,如果数据库迟迟不发回数据(比如:
- 查询结果太大;
- 网络延迟高;
- 数据库执行慢但未超时;
- 数据库卡住等),就会触发
socketTimeout
。
🧪 四、完整示例说明
✅ 示例代码:
String url = "jdbc:mysql://localhost:3306/testdb?connectTimeout=5000&socketTimeout=5000";
try (Connection conn = DriverManager.getConnection(url, "root", "password");
Statement stmt = conn.createStatement()) {
// 查询一个需要执行很久且返回大量数据的 SQL
ResultSet rs = stmt.executeQuery(