/ / Cómo evitar conexiones obsoletas de MySQL / Hibernate (MySQLNonTransientConnectionException) - java, mysql, hibernate

Cómo evitar conexiones obsoletas de MySQL / Hibernate (MySQLNonTransientConnectionException) - java, mysql, hibernate

Tengo una aplicación web de Java que utiliza Hibernate y MySQL. Si el sitio no se usa por unos días, la conexión de MySQL se desactiva y me encuentro con la siguiente excepción:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.

De la experiencia usando JDBC en bruto es posibleconfigure la conexión para intentar recuperarse de errores o conexiones obsoletas, pero no sé cómo hacerlo utilizando Hibernate. No estoy llamando explícitamente a close () en ningún lugar (pero estoy apostando a que Hibernate lo hace en algún lugar en el fondo).

¿Alguien sabe lo que debo hacer?

Respuestas

4 para la respuesta № 1

¿Qué grupo de conexión estás usando?

los Sugerencia de hibernación no es usar la agrupación integrada, sino usar la fuente de datos del servidor de aplicaciones o algo así como Commons DBCP o C3PO.


3 para la respuesta № 2

Tuve ese problema El uso de la agrupación de conexiones (c3p0) hizo que desapareciera. También es una buena idea en general utilizar un conjunto de conexiones.


2 para la respuesta № 3

Gracias por el consejo. Para la posteridad ", cambié el hibernate.cfg.xml de lo siguiente:

<property name="connection.url">jdbc:mysql://localhost/FooDB</property>
<property name="connection.username">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.password">secret</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

... a lo siguiente:

<property name="connection.datasource">java:/comp/env/jdbc/FooDB</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

Esto también requirió agregar una entrada de "contexto" estándar en el contexto.xml de mi aplicación web:

<Resource name="jdbc/FooDB"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="root"
password="secret"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/ss?autoReconnect=true" />


1 para la respuesta № 4

Tuvimos un problema similar de hibernación de conexión mysql que se agotó el tiempo de espera. Así que probamos C3P0, con la siguiente configuración:

<property name=c3p0.acquire_increment>1</property>
<property name=c3p0.idle_test_period>3600</property>
<property name=c3p0.max_statements>0</property>
<property name=c3p0.min_size>1</property>
<property name=c3p0.timeout>3605</property>
<property name=hibernate.c3p0.preferredTestQuery>select 1;</property>

Hibernate connection_pool tamaño se estableció en 1.

Esto hizo que el problema del tiempo fuera desapareciera. Pero empezamos a enfrentar otro problema. Largas esperas Tenemos un servicio (servlet que se ejecuta en jboss), que recibe algo así como 5-6 solicitudes por segundo. Cada solicitud debe conectarse a mysql mediante hibernación. La mayoría de nuestras solicitudes seleccionan, con una inserción / actualización cada 5 a 6 de las solicitudes. Normalmente, el tiempo de servicio de solicitud para nosotros es de 2-3 ms para seleccionar y de 40 a 50 ms para insertar / actualizar. ¡Pero, después de usar la configuración C3P0 anterior, vimos que cada solicitud completada después de una actualización estaba tomando casi 4-5 minutos! De nuestros registros, parecía que al azar una solicitud de selección se atascaría y podría completarse solo después de que una solicitud de actualización fuera recibida y atendida.

El problema anterior desaparece si eliminamos la configuración C3P0. ¿Alguien puede sugerir lo que podríamos estar haciendo mal?

Aquí está la configuración completa de hibernación para referencia:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://xxx.xxx.xxx</property>
<property name="connection.username">xxx</property>
<property name="connection.password">xxx</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="show_sql">true</property>
<!-- Transaction isolation 2 = READ_COMMITTED -->
<property name="connection.isolation">2</property>
<property name="connection.autocommit">true</property>
<!-- configuration pool via c3p0-->
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">3600</property> <!-- seconds -->
<property name="c3p0.max_size">1</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.timeout">3605</property> <!-- seconds -->
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
</session-factory>
</hibernate-configuration>

1 para la respuesta № 5
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">120</property> <!-- seconds -->
<property name="c3p0.max_size">100</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">10</property>
<property name="c3p0.timeout">180</property> <!-- seconds -->

anula esta configuración en tu archivo de configuración. Te ayudará.