通过连接复原能力 ,JDBC 驱动程序可以透明地还原中断的空闲连接,并在连接失败时重试初始连接。 本文涵盖控制此行为的两个连接字符串属性(connectRetryCount 和 connectRetryInterval),以及驱动程序用于检测已断开的空闲连接的 keepalive 设置。 从 Microsoft JDBC Driver 10.2.0 开始,SQL Server提供连接复原能力。 重新连接中断的空闲连接需要SQL Server 2014 或更高版本,或Azure SQL 数据库。
Tip
连接复原能力只会重试 初始连接,并静默恢复已断开的空闲连接。 若要自动重试失败语句(例如死锁受害者 1205 或锁超时 1222),或者使用自定义错误号扩展连接重试列表(例如,Azure SQL暂时性错误(如 40197 或 40613),请使用可配置的重试逻辑。 CRL 是基于规则的,错误类型和回退策略由你来选择,并且它可与本文介绍的功能配合使用。
JDBC 驱动程序重试方式
JDBC 驱动程序提供三个独立的重试机制。 它们协同工作,因此你可以一次性使用所有这些方法:
| 机制 | 它的作用是什么 | 了解详细信息的位置 |
|---|---|---|
| 空闲连接复原能力 | 以透明方式还原中断的空闲连接(例如,由服务器或负载均衡器关闭的共用连接)。 | 检测已断开的空闲连接(本文) |
| 初始连接重试 | 对于内置的暂时性错误列表中的错误,会按照固定计划重试失败的初始连接。 | 重试初始连接 (本文) |
| 可配置的重试逻辑 (CRL) | 针对失败的语句和自定义错误号的基于规则的重试 Microsoft JDBC 驱动程序 12.10 中引入。 | 可配置的重试逻辑 |
重试初始连接
JDBC 驱动程序包含两个连接属性,用于控制驱动程序在重试初始连接之前等待的频率和时长。 将这些属性添加到连接字符串或通过数据源属性设置它们。
| 关键字 | 值 | 默认值 | 说明 |
|---|---|---|---|
connectRetryCount |
介于 0 和 255 之间(含限值)的整数 | 1 | 在放弃尝试之前,尝试建立或重建连接的最大次数。 默认情况下,驱动程序进行一次重试尝试。 值为 0 时,将禁用重试。 |
connectRetryInterval |
介于 1 和 60 之间(含限值)的整数 | 10 | 连接重试的间隔时间(以秒为单位)。 驱动程序在检测到中断的空闲连接时立即尝试重新连接,然后在重试前等待 connectRetryInterval 几秒钟。 当 connectRetryCount 为 0 时,将忽略此属性。 |
如果 connectRetryCount * connectRetryInterval 大于 loginTimeout,则驱动程序会在达到 loginTimeout 后停止尝试连接。 否则,它将一直持续到 connectRetryCount 用尽。
这些属性仅重试 暂时性连接错误的内置列表。 有关涵盖的错误的完整列表(4060、40197、40501、40613、49918-49920 等),请参阅 内置暂时性连接错误列表。 若要将自定义错误号添加到此集,或将其完全替换,请在retryConn中使用。 若要重试执行失败的语句,请使用同一篇文章中的 retryExec。
设置属性
在 JDBC URL 中、在 Properties 对象上,或在 SQLServerDataSource 上设置 connectRetryCount 和 connectRetryInterval。
在 JDBC URL 中:
jdbc:sqlserver://server;databaseName=db;connectRetryCount=3;connectRetryInterval=10
使用 Properties 对象。 本文中的Java代码片段省略导入和类包装器,以简洁起见。
Properties props = new Properties();
props.setProperty("user", "...");
props.setProperty("password", "...");
props.setProperty("connectRetryCount", "3");
props.setProperty("connectRetryInterval", "10");
Connection c = DriverManager.getConnection("jdbc:sqlserver://server;databaseName=db", props);
使用 SQLServerDataSource:
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("server");
ds.setDatabaseName("db");
ds.setUser("...");
ds.setPassword("...");
ds.setConnectRetryCount(3);
ds.setConnectRetryInterval(10);
检测已断开的空闲连接
典型的空闲连接是指处于连接池中的连接。 驱动程序在大约 30 秒后将连接视为空闲状态,没有活动。 服务器,或位于客户端与服务器之间的某个网络设备,都可能关闭空闲连接,因此驱动程序需要一种方法,以便在执行下一次查询之前检测到套接字已失效。
为了检测中断的空闲连接,驱动程序依赖于套接字级别的 TCP keepalive 包。 在 Linux 和 Java 11 或更高版本上,驱动程序会自动启用保活数据包,间隔为 30 秒(KeepAliveTime);发生故障时,两次重试之间延迟 1 秒(KeepAliveInterval)。
重要
在Windows和Java 11 或更早版本上,必须在操作系统中手动配置 keepalives,以利用中断的空闲连接恢复。 有关如何配置 keepalive 的信息,请参阅连接到 Azure SQL 数据库。
限制
如果满足以下任一条件,驱动程序将无法还原中断的空闲连接:
- 有一个未完全分析或缓冲的开放结果集。
- 连接针对Azure SQL切换了数据库。
- 存在一个未完成的事务。