数据库重新启动后尝试重新连接 jdbc 池数据源

Posted

技术标签:

【中文标题】数据库重新启动后尝试重新连接 jdbc 池数据源【英文标题】:attempt to reconnect jdbc pool datasource after database restarts 【发布时间】:2012-07-03 08:11:54 【问题描述】:

我有一个带有 Java 后端的 Web 应用程序,它使用 Tomcat jdbc-pool 进行数据库连接。这很好用。

但是我在将其导出到其他位置之前尝试对其进行万无一失,最近发生了一个场景,有人重新启动了 SQL Server 数据库服务,但没有重新启动 Tomcat 服务。这导致了一个 SQLException: java.sql.SQLException: I/O Error: Connection reset by peer: socket write error 直到我重新启动 Tomcat,强制 jdbc-pool 数据源重新连接。

我在 Tomcat jdbc-pool 文档中寻找某种配置来告诉数据源尝试重新连接,但我找不到任何东西。

有谁知道这是否有某种配置,或者我应该在每次请求之前检查这个条件吗?

【问题讨论】:

【参考方案1】:

不是 100% 确定这是否是您的问题,但在 http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency 上,它说您可以使用 testOnBorrowvalidationQuery

<Resource type="javax.sql.DataSource"
            ...
            testOnBorrow="true"
            validationQuery="SELECT 1"
            removeAbandoned="true"
            />

【讨论】:

我试图避免验证查询开销,并在同一链接中找到了另一种方法,使用 timeBetweenEvictionRunsMillis="5000"minEvictableIdleTimeMillis="5000"minIdle="0" 似乎可以解决问题,谢谢。 @Geronimo:好吧,我昨天赞成你的评论,但今天我意识到使用minIdle="0" 实际上可能更糟:它实际上是在 5 秒不活动后关闭连接,不管它是否正常。所以我不确定更糟糕的是:在每次查询之前执行SELECT 1,或者必须每隔 5 秒重新连接一次不活动...... testOnBorrow="true" 会在发现旧连接关闭时自动启动新连接? 那个原链接没了,但是被返航机记录下来了:web.archive.org/web/20180521112213/http://www.tomcatexpert.com/…【参考方案2】:

在检查相同的问题时,我遇到了这篇文章,其中包含所有应用服务器的自动连接配置。

以下是我在tomcat中用于自动连接的配置,供参考。

    <Resource auth="Container"
driverClassName="oracle.jdbc.OracleDriver"
initialSize="5"
maxActive="120"
maxIdle="5"
maxWait="5000"
name="jdbc/oracle/myds"
password="secret"
poolPreparedStatements="true"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:@DBHOSTNAME:1521/ServiceName"
username="testuser"
validationQuery="select 1 from tab"
testOnBorrow="true"/>

可以在Datasource autoreconnect in Java Application Servers 中找到所有应用服务器的完整自动连接配置。

【讨论】:

【参考方案3】:

只是为了补充 Natan Cox 的回答

参考 - http://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html#Common_Attributes

<Resource type="javax.sql.DataSource"
        ...
        testOnBorrow="true"
        validationQuery="SELECT 1"
        removeAbandoned="true"
        />

相对于 Geronimo,我仍然想使用 validationQuery

数据库验证查询注释

hsqldb - select 1 from INFORMATION_SCHEMA.SYSTEM_USERS

甲骨文 - select 1 from dual

DB2 - select 1 from sysibm.sysdummy1

mysql - select 1

Microsoft SQL Server - select 1

postgresql - select 1

ingres - select 1

德比 - values 1

H2 - select 1

火鸟 - select 1 from rdb$database

参考 - DBCP - validationQuery for different Databases

【讨论】:

testOnBorrow="true" 如果发现旧连接已关闭,是否会自动启动新连接?

以上是关于数据库重新启动后尝试重新连接 jdbc 池数据源的主要内容,如果未能解决你的问题,请参考以下文章

JDBC连接池:DB重启后连接不回收

glassfish JDBC 连接池

MySql & JDBC & 连接池 & 总结

Druid 连接池,重启Mysql数据库后,Druid会自动重新连接不,该在哪配置?

jdbc数据库连接池

JDBC 连接:超时后未重新连接