Spring上的DBCP和Hibernate,不会重新打开死连接,为啥?

Posted

技术标签:

【中文标题】Spring上的DBCP和Hibernate,不会重新打开死连接,为啥?【英文标题】:DBCP and Hibernate on Spring, doesn't re-open dead connections, why?Spring上的DBCP和Hibernate,不会重新打开死连接,为什么? 【发布时间】:2011-08-03 22:03:22 【问题描述】:

我在 Spring 项目中使用 Hibernate 和 DBCP 来管理 mysql 连接。

一切正常。唯一的问题是,如果应用程序长时间保持静止,它会抛出异常,因为连接已死(如果我在应用程序启动时重新启动 mySQLd 也是如此)。这没什么大不了的,因为用户将获得异常页面(或自定义页面)并且重新加载将解决问题。但我想解决它。这是例外的一部分:

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** 开始嵌套异常 **

java.io.EOFException 消息:无法从服务器读取响应。预计读取 4 个字节,在连接意外丢失之前读取 0 个字节。

堆栈跟踪:

java.io.EOFException:无法从服务器读取响应。预计读取 4 个字节,在连接意外丢失之前读取 0 个字节。

我搜索了一下,发现使用 mysql 我应该将 dbcp.BasicDataSource 属性 testOnBorrow 设置为 true,这是我在我的 servlet-context.xml 中完成的:

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://$mySQL.host/$mySQL.db" />
    <property name="username" value="$mySQL.user" />
    <property name="password" value="$mySQL.pass" />
    <property name="testOnBorrow" value="true"></property>
</bean>

但问题仍然存在。有什么线索吗?

解决方案!我用过:

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://$mySQL.host/$mySQL.db" />
    <property name="username" value="$mySQL.user" />
    <property name="password" value="$mySQL.pass" />
    <property name="testOnBorrow" value="true"></property>
    <property name="validationQuery" value="SELECT 1"></property>
</bean>

【问题讨论】:

【参考方案1】:

如果你设置了testOnBorrow,你还必须设置validationQuery -

validationQuery - 将用于 验证来自该池的连接 在将它们返回给调用者之前。 如果指定,此查询必须是 返回的 SQL SELECT 语句 至少一排。

我还设置了timeBetweenEvictionRunsMillis,所以死连接将从池中被逐出。

【讨论】:

这是否意味着每次Hibernate从DBCP借一个连接时都会运行这个查询???是不是太重了? 它应该是一个运行速度非常快的小查询。假设 Hibernate 为每个连接运行几个不小的查询,那么再一个小查询应该不会影响性能。 hm.... 是的,我明白了,我使用了 SELECT 1(在 dbcp wiki 上建议)。无论如何,我认为hibernate每次打开会话时都会获得连接。这意味着大约每次控制器处理请求时。我希望这只是一个与 mySQL 相关的问题。

以上是关于Spring上的DBCP和Hibernate,不会重新打开死连接,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

spring整合hibernate时出错(已经导入commons-dbcp2-2.1.1.jar和commons-pool2-2.1.jar)

spring jdbc

DBCP

spring02

spring 链接池

java程序访问数据库,dbcp连接池,hibernate连接总是报池连接用光了/JDBC连接没有报错