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)