Подтвердить что ты не робот

DBCP и Hibernate на Spring, не восстанавливает мертвые соединения, почему?

Я использую Hibernate и DBCP для управления соединениями mySQL, все в проекте Spring.

Все работает нормально. Единственная проблема заключается в том, что если приложение остается в течение длительного времени, оно выдает исключение, потому что соединение мертво (то же самое, если я перезапущу mySQLd, когда приложение встанет). Это не очень важно, потому что пользователь получит страницу исключения (или пользовательскую), и перезагрузка решит проблему. Но я бы хотел его решить. Вот часть исключения:

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

** НАЧАТЬ НЕИСПРАВНОСТЬ ИСКЛЮЧЕНИЯ **

java.io.EOFException СООБЩЕНИЕ: Не удается прочитать ответ с сервера. Ожидается, что прочитайте 4 байта, прочитайте 0 байт до того, как соединение было неожиданно потеряно.

StackTrace:

java.io.EOFException: не удается прочитать ответ с сервера. Ожидается, что прочитайте 4 байта, прочитайте 0 байт до того, как соединение было неожиданно потеряно.

Я googled вокруг, и я обнаружил, что с 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>
4b9b3361

Ответ 1

Если вы установили testOnBorrow, вы также должны установить validationQuery -

validationQuery - SQL-запрос, который будет использоваться для проверять соединения из этого пула перед тем как вернуть их вызывающему абоненту. Если указано, этот запрос ДОЛЖЕН быть Оператор SQL SELECT, возвращающийся в менее одной строки.

Я также установил timeBetweenEvictionRunsMillis, чтобы мертвые соединения были выведены из пула.