2009-01-24 7 views
42

Uso Hibernate junto con MySQL 5.1.30.¿Cuáles son los ajustes requeridos de C3P0 para hibernación para evitar interbloqueos?

que tienen las siguientes bibliotecas:

  • c3p0-0.0.1.2.jar
  • mysql-connector-java-5.0.3-bin.jar
  • hibernate3.jar

uso un hibernate.cfg.xml para la configuración:

<!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
    <session-factory> 
     <!-- Database connection settings --> 
     <property name="connection.driver_class">org.gjt.mm.mysql.Driver</property> 

     <property name="connection.url">jdbc:mysql://localhost/fooDatatbase</property> 
    <property name="connection.username">foo</property> 
    <property name="connection.password">foo123</property> 

     <!-- Use the C3P0 connection pool provider --> 
    <property name="hibernate.c3p0.min_size">5</property> 
    <property name="hibernate.c3p0.max_size">20</property> 
    <property name="hibernate.c3p0.timeout">300</property> 
    <property name="hibernate.c3p0.max_statements">50</property> 
    <property name="hibernate.c3p0.idle_test_periods">3000</property>  

     <!-- SQL dialect --> 
     <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 

     <!-- Enable Hibernate's automatic session context management --> 
     <property name="current_session_context_class">thread</property> 

     <!-- Disable the second-level cache --> 
     <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 

     <!-- Echo all executed SQL to stdout --> 
     <property name="show_sql">true</property> 

     <mapping resource="databaselayer/mail/Mail.hbm.xml"/> 
     <mapping resource="databaselayer/courses/Course.hbm.xml"/> 
     <mapping resource="databaselayer/price/Price.hbm.xml"/>   
     <mapping resource="databaselayer/contact/Contact.hbm.xml"/> 
     <mapping resource="databaselayer/artists/Musician.hbm.xml"/> 
     <mapping resource="databaselayer/concerts/Concert.hbm.xml"/>  
     <mapping resource="databaselayer/welcome/Welcome.hbm.xml"/> 
     <mapping resource="databaselayer/information/Information.hbm.xml"/>        
    </session-factory> 
</hibernate-configuration> 

En la persistencia Java con Hibernate libro, se explican las opciones de configuración c3p0:

  • hibernate.c3p0.min_size Este es el número mínimo de conexiones JDBC que C3P0 mantiene listo en todo veces
  • hibernate.c3p0.max_size Este es el número máximo de conexiones en el grupo. Se arroja una excepción en el tiempo de ejecución si este número se agota.
  • hibernate.c3p0.timeout Especifique el período de tiempo de espera (en este caso, 300 segundos) después del cual se elimina una conexión inactiva del grupo).
  • hibernate.c3p0.max_statements Número máximo de declaraciones que se almacenarán en caché. El almacenamiento en caché de declaraciones preparadas es esencial para un mejor rendimiento con Hibernate.
  • hibernate.c3p0.idle_test_periods Este es el tiempo de inactividad en segundos antes de que una conexión se valide automáticamente.

Yo uso Java 1.5.0_09 y tomcat 6.0. Tengo tres aplicaciones implementadas en Tomcat. Cada uno de ellos usa hibernación con un archivo de configuración casi equivalente al que se muestra arriba (solo cambian el nombre de usuario, el nombre de base de datos, la contraseña y las resoluciones de mapeo).

Lamentablemente con la configuración anterior, después de algunas horas corriendo consigo algunos desagradables Errores de interbloqueo que terminan matando a tomcat.

Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]2437d -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]1dc5cb7 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]9cd2ef -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]4af355 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]1275fcb -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Jan 22, 2009 3:29:35 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 

Esto parece ser un error que muchas personas ya tienen. He cambiado mi configuración tratando de seguir la solución descrita aquí http://forum.hibernate.org/viewtopic.php?p=2386237 a:

<property name="hibernate.c3p0.acquire_increment">1</property> 
<property name="hibernate.c3p0.min_size">0</property> 
<property name="hibernate.c3p0.max_size">48</property> 
<property name="hibernate.c3p0.timeout">0</property> 
<property name="hibernate.c3p0.max_statements">0</property> 

Con la nueva configuración, no consigo interbloqueos, pero me sale:

WARNING: SQL Error: 0, SQLState: 08S01 
Jan 24, 2009 5:53:37 AM org.hibernate.util.JDBCExceptionReporter logExceptions 
SEVERE: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.io.EOFException 

STACKTRACE: 

java.io.EOFException 
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913) 

¿Alguien sabe lo que estoy haciendo mal, y cómo puedo configurar c3p0 correctamente?

+1

Claramente, debe quitar su perno de restricción. –

+0

Supongo que cada aplicación obtiene su propio grupo de aplicaciones porque tengo tres archivos hibernate.cfg.xml como el publicado en la carpeta WEB-INF/classes de las aplicaciones. –

+1

¿Todos tienen el mismo nombre JNDI? Si es así, le están pidiendo a Tomcat que busque la conexión desde el mismo grupo. Necesita un nombre JNDI separado para cada proyecto para que tengan un grupo individual. Debería ver 3 grupos JNDI en la herramienta de administración de Tomcat. Si estoy en lo cierto, solo verás uno ahora. – duffymo

Respuesta

0

¿Las tres aplicaciones comparten el mismo grupo de conexiones, o cada una obtiene las suyas? Yo recomendaría este último.

+0

Supongo que cada aplicación obtiene su propio grupo de aplicaciones porque tengo tres archivos hibernate.cfg.xml como el publicado en la carpeta WEB-INF/classes de las aplicaciones. –

8

No hay una respuesta definitiva a esta pregunta, ya que cambia de una aplicación a otra dependiendo del uso & patrón de carga.

El primer punto es consultar el enlace https://www.hibernate.org/214.html, ya que parece que lo has hecho y seguido. Aquí hay algunos consejos;

  • numHelperThreads: Hilos de ayuda que no tienen bloqueos contendidos. Difundir estas operaciones en varios subprocesos
  • maxStatements: el tamaño del caché global PreparedStatement de c3p0.
  • maxStatementsPerConnection: el número de PreparedStatements c3p0 guardará en la memoria caché una única conexión agrupada.
  • maxAdministrativeTaskTime: Parámetro de que la fuerza una llamada a interrupción de la rosca tarea() método si una tarea excede un límite de tiempo establecido

primer lugar tres parámetros puede mejorar o reducir el rendimiento basado en el valor establecido donde como sucesivamente parámetro puede interrumpir el hilo después de establecer el límite y dar un cambio para ejecutarlo en otro hilo.

valores aproximados

  • numHelperThreads = 6
  • maxStatements = 100
  • maxStatementsPerConnection = 12
  • maxAdministrativeTaskTime = necesidad de tiempo suficiente para que consulta pesada se puede ejecutar en la producción

maxStatements y maxStatementsPerConnection deberían probarse durante algunos meses como pocos puntos de publicación a dead lock debido a estos parámetros.

También será útil hacer referencia a estos enlaces;

1

Eso es una versión muy antigua de Connector/J. Para asegurarse de que no está luchando contra un fallo conocido y fijo, me gustaría empezar por conseguir la más reciente (5.0.8):

http://dev.mysql.com/downloads/connector/j/5.0.html

Eso EOFException de MysqlIO es un poco sospechoso. En el uso normal/sin errores, nunca deberías obtener errores de esa capa.

42

En realidad este es probablemente demasiado tarde, pero el problema es bastante simple: hibernate.c3p0.idle_test_periods no debe ser mayor que hibernate.c3p0.timeout o conexiones cerradas por la base de datos no se detectará correctamente.

Por otra parte, las advertencias de detección de estancamiento se ven como una parte de su código no devuelve correctamente las conexiones a la piscina (es decir session.close())

Las excepciones MysqlIO se producen cuando la aplicación está inactivo y MySQL cierra la conexión en el servidor.Ahora bien, si C3P0 no verifica correctamente si una conexión todavía está realmente conectada, obtienes las EOFExcepciones.

Espero que esto pueda ser útil.

3

Los hibernate.c3p0.idle_test_periods tiene que ser menor que h * ibernate.c3p0.timeout * porque el primero es sólo sólo un valor de tiempo de hibernación, donde comprobación de las conexiones inactivas y tratar de cerrarla.

Mientras tanto, el segundo es cuánto tiempo debe expulsarse una conexión.

Si idle_test_periods es mayor que el parámetro de tiempo de espera que hibernación, busque cualquier cosa que sea nula o no exista en el sistema. Al menos lo entendí de esta manera.

-1
<property name="hibernate.c3p0.timeout">300</property>  
    <property name="hibernate.c3p0.idle_test_periods">3000</property>  

idle_test_period El valor debe ser inferior al valor de tiempo de espera excedido.

Cuestiones relacionadas