tutorial timebetweenevictionrunsmillis removeabandoned que example conexiones java spring tomcat deadlock apache-commons-dbcp

java - timebetweenevictionrunsmillis - Problema de interbloqueo en DBCP implementado en Tomcat



tomcat jdbc tutorial (5)

Estoy usando el origen de datos DBCP (con la configuración predeterminada) en la configuración de Spring para administrar mis conexiones a la base de datos, y me encuentro con una condición de interbloqueo cuando aumenta el número de clientes.

Encontré que hay un problema de interbloqueo en DBCP 1.2.1 que estaba usando, que se suponía que se resolvía en 1.4. Así que actualicé a 1.4, pero el problema aún persiste.

En el volcado de hilos, hay muchos subprocesos bloqueados con el siguiente seguimiento de pila en la parte superior:

java.lang.Thread.State: WAITING on org.apache.commons.pool.impl.GenericObjectPool$Latch@b6b09e at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:485) at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104) at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106) at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044) at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:200) at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:350) at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:261) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:160) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:631)

Cualquier sugerencia es bienvenida!


¿Se aseguró de que la versión de commons-pool coincida con la versión de dbcp?

Además, no veo un interbloqueo en el seguimiento de pila, simplemente parece que tienes hilos en espera de que las conexiones se liberen ... ¿Cuántos hilos estás intentando conectar al mismo tiempo? ¿Cuántas conexiones has configurado para el grupo, etc.?

En la depuración de este tipo de casos, también es útil observar qué están haciendo los hilos que han obtenido una conexión.


Creo que esto se debe a que no se cierran las conexiones en el código de tu aplicación, por lo que simplemente te quedas sin conexiones en el grupo. Tal vez debería intentar establecer la propiedad "removeAbandoned" en DBCP. Esto se documenta en http://commons.apache.org/dbcp/configuration.html como

Al establecer esto en verdadero, se pueden recuperar conexiones de bases de datos de aplicaciones mal escritas que no logran cerrar una conexión.

¡La mejor de las suertes!


Incrementar la carga en la aplicación es un requisito cada vez mayor para las conexiones concurrentes. Como sus hilos se cuelgan en borrowConnection() , significa que no tiene suficientes ActiveConnections disponibles.

Incrkease maxActive en las propiedades de su maxActive de datos y establezca WHEN_EXHAUSTED_BLOCK en algún momento como 600ms - 1000ms . Obtendrá la excepción No element available solo después de transcurridos 600 ms -1000 ms.


Me enfrentaba a problemas similares y esto se resolvió siguiendo los pasos

  1. Cierre todos los recursos de la base de datos en la secuencia adecuada

    resultSet.close(); statement.close(); connection.close();

Diferentes controladores se implementan de manera diferente, algunos controladores aún se transferirían a la conexión si el conjunto de resultados subyacente no está cerrado.

  1. Los ajustes por defecto de Apache DBCP deben ser ajustados

dataSource.setDefaultAutoCommit(true);
dataSource.setMaxActive(700); // make sure db server has it 800 dataSource.setRemoveAbandoned(true); dataSource.setTestOnBorrow(true); dataSource.setLogAbandoned(true); dataSource.setTestWhileIdle(true); dataSource.setTestOnReturn(true); dataSource.setRemoveAbandonedTimeout(60);

Asegúrese de que el servidor de la base de datos pueda permitir más de 50 conexiones más que el número especificado en setMaxActive ya que el dbcp le da primero a x nuevas conexiones y luego intenta limpiar las conexiones que excedan el número de setMaxActive . En la limpieza, dbcp muestra que todas las conexiones no se cerraron en el servidor de registro / consola.