2009-04-08 17 views
15

MySQL parece tener un tiempo de espera de 8 horas en sus conexiones. Estoy ejecutando múltiples WAR en Tomcat utilizando Hibernate para ORM. Después de 8 horas (es decir, durante la noche), obtengo tuberías rotas cuando detecta una conexión inactiva.Hibernate, C3P0, Mysql - Broken Pipe

Ya he rastreado el código y estoy doblemente seguro de confirmar o deshacer todas las transacciones.

Aquí es mi hibernate.cfg.xml

<?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="hibernate.bytecode.use_reflection_optimizer">false</property> 
    <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property> 
    <property name="hibernate.connection.password"></property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost/test</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> 
    <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> 
    <property name="hibernate.current_session_context_class">thread</property> 
    <!--property name="hibernate.show_sql">true</property> 
    <property name="hibernate.format_sql">true</property--> 

    <property name="c3p0.min_size">3</property> 
    <property name="c3p0.max_size">5</property> 
    <property name="c3p0.timeout">1800</property> 
    <property name="c3p0.preferredTestQuery">SELECT 1</property> 
    <property name="c3p0.testConnectionOnCheckout">true</property> 
    <property name="c3p0.idle_test_period">100</property> <!-- seconds --> 

    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 
    <property name="cache.use_query_cache">false</property> 
    <property name="cache.use_minimal_puts">false</property> 
    <property name="max_fetch_depth">10</property> 

    <property name="hibernate.hbm2ddl.auto">update</property> 

    <!-- classes removed --> 

</session-factory> 

El parámetro pensé que habría fijado era el c3p0.idle_test_period - Su valor predeterminado es 0. Sin embargo, aún tenemos el problema de tubería rota después de 8 horas de correr. Si bien hay varios posts indexados a través de Google, ninguno llega a una respuesta satisfactoria.

Respuesta

23

Así que resulta que me faltaba una línea fundamental que permitió a c3p0 (los parámetros c3p0 estaba pellizcando estaban teniendo ningún efecto porque Hibernate estaba usando que está construido en la piscina de conexión - que se advierte apropiadamente no es adecuado para producción). En hibernate 2.x, al establecer la propiedad hibernate.c3p0.max_size se habilitó la agrupación de conexiones c3p0. Sin embargo, en 3.x debe especificar la siguiente propiedad -

<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 

Además, aquí están mis parámetros de configuración finales -

<property name="hibernate.c3p0.min_size">3</property> 
<property name="hibernate.c3p0.max_size">5</property> 
<property name="hibernate.c3p0.timeout">1800</property> 
<property name="hibernate.c3p0.idle_test_period">100</property> <!-- seconds --> 

Es bastante lamentable que tanto Hibernate y c3p0 tienen la documentación en pésimo A este respecto.

+0

Gracias, esto me ayudó. Estoy de acuerdo con el comentario de la documentación. Peor aún, la documentación de c3p0 le aconseja utilizar c3p0.properties para todos los demás, excepto los 5 anteriores, pero eso no funciona. Solo funciona cuando especificas en persistence.xml sin el prefijo de hibernación (como lo hiciste en tu cfg.xml original) – Sun

+0

Esto también me ayudó ... Estoy de acuerdo con la documentación :). Podría ser un poco más directo en su documentación. – Polaris878

+0

Si usó la configuración xml para CombPooledDataSource, la propiedad es 'idleConnectionTestPeriod' que necesita tener. –

2

Hay dos cosas pasando aquí. Se debe leer this article para más detalles, pero los de comida para llevar son:

  1. Se puede ajustar la configuración de MySQL wait_timeout a algo más de 8 horas, si se desea.
  2. La configuración de Hibernate debe incluir "hibernar". antes del "c3p0", p. hibernate.c3p0.idle_test_period en lugar de sólo c3p0.idle_test_period
+0

Voy a tratar de agregar el prefijo de hibernación hoy. No creo que la ampliación del wait_timeout de MySQL ayude ... Solo retrasaría el error de la tubería rota. – Mark

1

tengo varios problemas - - C3P0ConnectionProvider no se ha encontrado - Me resolverlo mediante el uso de la versión de hibernación c3p0

 <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>3.5.6-Final</version> 
    </dependency> 
      <!-- c3p0 --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-c3p0</artifactId> 
     <version>3.3.1.GA</version> 
    </dependency> 

- Tengo que wait_timeout tema en MySQL. Primero configuro /etc/my.cnf wait_timeout = 10 y luego modifiqué el valor de tiempo de inactividad para que fuera inferior al valor de wait_timeout, que Eso resolvió mi problema.

<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" /> <property name="hibernate.c3p0.acquire_increment" value="1" /> 
     <property name="hibernate.c3p0.idle_test_period" value="28690"/> 
     <property name="hibernate.c3p0.timeout" value="1800" /> 
     <property name="hibernate.c3p0.max_size" value="5" /> 
     <property name="hibernate.c3p0.min_size" value="3" /> 
     <property name="hibernate.c3p0.max_statement" value="50" /> 
     <property name="hibernate.c3p0.preferredTestQuery" value="select 1;"/> 
2

Esta es una solución cuando se tiene una tubería rota debido a la combinación de wait_timeout = 28800 seg de Tomcat (8h) y MaxIdleTime = 0 en c3p0:

He cambiado el gato local de wait_timeout a través de mi archivo .ini a 120seg (2 min).Y coloqué la siguiente:
MaxIdleTime = 100
idleConnectionTestPeriod = 0 (el mismo que default/como si no existiera)
otro:
acquireIncrement = 2
MinPoolSize = 2
maxPoolSize = 5
maxIdleTimeExcessConnections = 10

No tuve problemas con esta configuración.

¡No necesité utilizar idleConnectionTestPeriod!

Si el tiempo de espera de Tomcat es 28800 segundos, y maxIdleTime es 25200, significa que c3p0 cerrará la conexión inactiva en 3600sec (1h) antes, antes de que tomcat arroje una excepción de "tubería interrumpida". ¿No es así?

Como puede ver, no tengo problemas para proporcionar solo maxIdleTime.

Por desgracia, los siguientes:
maxIdleTime
idleConnectionTestPeriod
configuring_connection_testing
testConnectionOnCheckin
no explican demasiado los casos de esquina.

Y, por cierto, aquí es cómo abrir el archivo del Tomcat my.ini con Notepad ++: http://drupal.org/node/32715#comment-4907440

Cheers,
Déspota

1

que estaba recibiendo el mismo problema y se tomó el tiempo para averiguar la solución.

Uso Hibernate 4.0.1 y mysql 5.1 (sin framework de primavera) y estaba enfrentando el problema. Primero asegúrese de haber configurado correctamente los frascos c3p0, que son esenciales.

que utiliza estas propiedades en hibernate.cfg.xml

<property name="hibernate.c3p0.validate">true</property> 
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> 
<property name="hibernate.c3p0.min_size">5</property> 
<property name="hibernate.c3p0.max_size">20</property> 
<property name="hibernate.c3p0.max_statements">50</property> 
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property> 
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property> 
<property name="hibernate.c3p0.idle_test_period">10</property> 
<property name="hibernate.c3p0.acquireRetryAttempts">5</property> 
<property name="hibernate.c3p0.acquireRetryDelay">200</property> 
<property name="hibernate.c3p0.timeout">40</property> 

Pero es de ninguna utilidad porque C3p0 todavía estaba tomando las propiedades por defecto no las propiedades que yo pongo en hibernate.cfg.xml, puede verifíquelo en los registros. Entonces, busqué en muchos sitios web la solución adecuada y finalmente se me ocurrió esto. elimine las propiedades C3p0 en cfg.xml y cree c3p0-config.xml en la ruta raíz (junto con cfg.xml) y establezca las propiedades de la siguiente manera.

<c3p0-config> 
<default-config> 
<property name="automaticTestTable">con_test</property> 
<property name="checkoutTimeout">40</property> 
<property name="idleConnectionTestPeriod">10</property> 
<property name="initialPoolSize">10</property> 
<property name="maxPoolSize">20</property> 
<property name="minPoolSize">5</property> 
<property name="maxStatements">50</property> 
<property name="preferredTestQuery">SELECT 1;</property> 
<property name="acquireRetryAttempts">5</property> 
<property name="acquireRetryDelay">200</property> 
<property name="maxIdleTime">30</property> 
</default-config> 
</c3p0-config> 

pero si se ejecuta, ORM toma la conexión JDBC pero no C3p0 agrupación de conexiones porque hay que añadir estas propiedades en hibernate.cfg.xml

<property name="hibernate.c3p0.validate">true</property> 

<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> 

ahora todo funciona bien (por lo menos funcionó bien para mí) y el problema está resuelto.

revise lo siguiente para las referencias.

http://www.mchange.com/projects/c3p0/index.html#configuring_connection_testing

https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool

espero que esto resuelve su problema.

Cuestiones relacionadas