2011-04-12 8 views
10

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

Respuesta

11

Si establece testOnBorrow también debe establecer validationQuery -

validationQuery - La consulta SQL que se utiliza para conexiones validar de este grupo antes de devolverlos a la persona que llama. Si se especifica, esta consulta DEBE ser una instrucción SQL SELECT que devuelve al menos una fila.

También he creado timeBetweenEvictionRunsMillis por lo que las conexiones inactivas serán desalojados de la piscina.

+0

¿Esto significa que esta consulta se ejecutará cada vez que Hibernate tome prestada una conexión de DBCP ??? ¿No es esto demasiado pesado? – gotch4

+0

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

+0

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

Cuestiones relacionadas