Estoy usando Hibernate y DBCP para administrar conexiones mySQL, todo en un proyecto de Spring.DBCP e Hibernate on Spring, no vuelve a abrir conexiones muertas, ¿por qué?
Todo funciona bien. El único problema es que si la aplicación se queda quieta durante un tiempo prolongado, arrojará una excepción porque la conexión está muerta (lo mismo si reinicio mySQLd cuando la aplicación está activa). No es gran cosa porque el usuario obtendrá la página de excepción (o la personalizada) y una recarga resolverá el problema. Pero me gustaría resolverlo. Aquí es parte de la excepción:
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
** ** COMENZAR excepción jerarquizada
java.io.EOFException mensaje: No se puede leer la respuesta del servidor. Se espera que lea 4 bytes, lea 0 bytes antes de que la conexión se pierda inesperadamente.
StackTrace:
java.io.EOFException: No se puede leer la respuesta del servidor. Se espera que lea 4 bytes, lea 0 bytes antes de que la conexión se pierda inesperadamente.
que googled alrededor y he encontrado que con MySQL debería establecer la propiedad testOnBorrow
dbcp.BasicDataSource
a true
, que he hecho en mi 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>
pero el problema persiste. ¿Alguna pista?
¡Solución! Solía:
<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>
¿Esto significa que esta consulta se ejecutará cada vez que Hibernate tome prestada una conexión de DBCP ??? ¿No es esto demasiado pesado? – gotch4
Debe ser una pequeña consulta que se ejecuta muy rápido. Suponiendo que Hibernate ejecuta varias consultas no pequeñas para cada conexión, una consulta más pequeña no debería afectar el rendimiento. – Tarlog
hm .... Sí, lo veo, usé SELECT 1 (se sugiere en la wiki de dbcp). De todos modos, creo que hibernate tendrá una conexión cada vez que abra una sesión. Esto significa aproximadamente cada vez que el controlador procesa una solicitud. Espero que esto sea solo un problema relacionado con mySQL. – gotch4