如何实现Quarkus连接池容错?解决无效连接复用问题
Quarkus 2.16.5 + JTDS驱动:网络恢复后连接池无效连接问题解决
我开发的Quarkus 2.16.5应用搭配MSSQL Server数据库和JTDS驱动,已经配置了validation-query和background-validation,但网络中断恢复后,依然会出现连接已关闭的无效状态错误。想找到配置方式阻止应用使用无效连接,并将它们从连接池中移除。
错误信息
Caused by: java.sql.SQLException: Invalid state, the Connection object is closed. at net.sourceforge.jtds.jdbc.JtdsConnection.checkOpen(JtdsConnection.java:1744) at net.sourceforge.jtds.jdbc.JtdsConnection.prepareStatement(JtdsConnection.java:2448) at io.agroal.pool.wrapper.ConnectionWrapper.prepareStatement(ConnectionWrapper.java:658) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
当前数据源配置
quarkus.datasource.jdbc.min-size=5 quarkus.datasource.jdbc.max-size=20 quarkus.datasource.jdbc.initial-size=5 quarkus.datasource.jdbc.acquisition-timeout=10 quarkus.datasource.jdbc.background-validation-interval=5 quarkus.datasource.jdbc.validation-query-sql=SELECT 1 quarkus.transaction-manager.default-transaction-timeout=600 quarkus.datasource.db-kind=other quarkus.datasource.username=sa quarkus.datasource.password=123456 quarkus.datasource.jdbc.url=jdbc:jtds:sqlserver://sqlserver-local/MYDB; quarkus.datasource.jdbc.driver=net.sourceforge.jtds.jdbc.Driver quarkus.hibernate-orm.dialect=org.hibernate.dialect.SQLServerDialect
解决方案
1. 开启连接获取时的验证
仅靠后台定期验证存在时间差,两次检查间隔内可能已有连接失效。添加以下配置,每次获取连接时直接验证有效性:
quarkus.datasource.jdbc.validation-query-on-acquisition=true
2. 配置连接生命周期与泄漏检测
强制连接在指定时间后被替换,同时检测长期未归还的泄漏连接:
# 连接最大生命周期(单位:秒,示例设为5分钟,可根据业务调整) quarkus.datasource.jdbc.max-lifetime=300 # 泄漏检测间隔(单位:秒) quarkus.datasource.jdbc.leak-detection-interval=5
3. 优化JTDS驱动连接URL
给JDBC URL增加两个参数,让驱动主动维护连接、超时重连:
quarkus.datasource.jdbc.url=jdbc:jtds:sqlserver://sqlserver-local/MYDB;keepAlive=on;loginTimeout=10
keepAlive=on:驱动定期发送心跳包维持连接loginTimeout=10:设置连接超时时间,避免卡在无效连接上
4. 开启连接归还时的验证
连接用完归还到池里时也进行验证,及时清理无效连接:
quarkus.datasource.jdbc.validation-query-on-release=true
5. 升级JTDS驱动版本
当前使用的1.3.1版本较老,升级到1.3.2(最新稳定版)可修复部分连接相关bug:
<dependency> <groupId>net.sourceforge.jtds</groupId> <artifactId>jtds</artifactId> <version>1.3.2</version> </dependency>
修改后的完整配置示例
quarkus.datasource.jdbc.min-size=5 quarkus.datasource.jdbc.max-size=20 quarkus.datasource.jdbc.initial-size=5 quarkus.datasource.jdbc.acquisition-timeout=10 quarkus.datasource.jdbc.background-validation-interval=5 quarkus.datasource.jdbc.validation-query-sql=SELECT 1 # 新增获取时验证 quarkus.datasource.jdbc.validation-query-on-acquisition=true # 新增归还时验证 quarkus.datasource.jdbc.validation-query-on-release=true # 新增连接生命周期与泄漏检测 quarkus.datasource.jdbc.max-lifetime=300 quarkus.datasource.jdbc.leak-detection-interval=5 quarkus.transaction-manager.default-transaction-timeout=600 quarkus.datasource.db-kind=other quarkus.datasource.username=sa quarkus.datasource.password=123456 # 优化后的JDBC URL quarkus.datasource.jdbc.url=jdbc:jtds:sqlserver://sqlserver-local/MYDB;keepAlive=on;loginTimeout=10 quarkus.datasource.jdbc.driver=net.sourceforge.jtds.jdbc.Driver quarkus.hibernate-orm.dialect=org.hibernate.dialect.SQLServerDialect
内容的提问来源于stack exchange,提问作者Renato Silva
相关产品推荐
相关产品推荐

