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

发布于 2024-10-31 22:55:54 字数 1787 浏览 10 评论 0原文

我正在使用 Hibernate 和 DBCP 来管理 mySQL 连接,所有这些都在 Spring 项目中。

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

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

** BEGIN NESTED EXCEPTION **

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

STACKTRACE:

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>

I'm using Hibernate and DBCP to manage mySQL connections, all in a Spring project.

Everything is working fine. The only problem is that if the app stays still for a long time, it will throw a an exception because the connection is dead (same thing if I restart mySQLd when the application is up). It's not big deal because the user will get the exception page (or the custom one) and a reload will solve the problem. But I'd like to solve it. Here is part of the exception:

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

** BEGIN NESTED EXCEPTION **

java.io.EOFException
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

STACKTRACE:

java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

I googled around and I found that with mysql I should set the dbcp.BasicDataSource property testOnBorrow to true, which I've done in my 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>

But the problem persists. Any clues?

Solution! I used:

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫九 2024-11-07 22:55:54

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

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

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

If you set testOnBorrow you must also set validationQuery -

validationQuery - The SQL query that will be used to
validate connections from this pool
before returning them to the caller.
If specified, this query MUST be an
SQL SELECT statement that returns at
least one row.

I have also set timeBetweenEvictionRunsMillis so the dead connections will be evicted from the pool.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文