Opciones de agrupación de conexiones con JDBC: DBCP vs C3P0


312

¿Cuál es la mejor biblioteca de agrupación de conexiones disponible para Java / JDBC?

Estoy considerando los 2 candidatos principales (libre / de código abierto):

He leído mucho sobre ellos en blogs y otros foros, pero no pude tomar una decisión.

¿Hay alguna alternativa relevante a estos dos?

Respuestas:


181

DBCP está desactualizado y no tiene grado de producción. Hace un tiempo realizamos un análisis interno de los dos, creando un accesorio de prueba que generaba carga y concurrencia contra los dos para evaluar su idoneidad en condiciones de la vida real.

DBCP generó constantemente excepciones en nuestra aplicación de prueba y luchó por alcanzar niveles de rendimiento que C3P0 era más que capaz de manejar sin ninguna excepción.

C3P0 también manejó robustamente las desconexiones de DB y las reconexiones transparentes en el currículum, mientras que DBCP nunca recuperó las conexiones si el enlace se sacó de debajo. Peor aún, DBCP estaba devolviendo objetos de conexión a la aplicación para la que se había roto el transporte subyacente.

Desde entonces, hemos utilizado C3P0 en 4 de las principales aplicaciones web de consumo pesado y nunca hemos mirado atrás.

ACTUALIZACIÓN: Resulta que después de muchos años de estar sentado en un estante, la gente de Apache Commons ha sacado a DBCP de la inactividad y ahora es, una vez más, un proyecto desarrollado activamente. Por lo tanto, mi publicación original puede estar desactualizada.

Dicho esto, todavía no he experimentado el rendimiento de esta nueva biblioteca actualizada, ni he oído hablar de que sea de facto en ningún marco de aplicación reciente.


2
¡Gracias! ¿Qué tal la alternativa sugerida de Proxool? La versión actual de Hibernate viene con c3p0 y Proxool.
Dema

No hemos probado Proxool, pero me aseguraré de comprobarlo ahora :)
j pimmel

55
c3p0 tiene algunos inconvenientes. a veces no puede manejar los picos de conexión.
Janning

3
las cosas han cambiado mucho desde hace 4 años cuando publicaste esta respuesta por primera vez, ¿podrías agregar una actualización que comparta el escenario actual, si es posible?
Rajat Gupta

13
Recomiendo HikariCP , pero luego ayudé a escribirlo.
Brettw

177

Los invito a probar BoneCP : es gratis, de código abierto y más rápido que las alternativas disponibles (consulte la sección de referencia).

Descargo de responsabilidad: soy el autor, por lo que podría decir que soy parcial :-)

ACTUALIZACIÓN: A partir de marzo de 2010, sigue siendo alrededor de un 35% más rápido que el nuevo conjunto de Apache DBCP reescrito ("tomcat jdbc"). Ver enlace de referencia dinámica en la sección de referencia.

Actualización n. ° 2: (Dec '13) Después de 4 años en la cima, ahora hay un competidor mucho más rápido: https://github.com/brettwooldridge/HikariCP

Actualización n. ° 3: (Sep '14) Considere que BoneCP está en desuso en este momento, recomiende cambiar a HikariCP .

Actualización n. ° 4: (abril '15) - Ya no soy dueño del dominio jolbox.com


1
Realmente me encantaría solucionar problemas usando BoneCP como fuente de datos de Tomcat. El principal problema que tuve con esto fue que requería clases BoneCP en el directorio lib de tomcat, así como las clases log4j y google. Hacer esto hizo que las agrupaciones de conexiones funcionaran (no había funcionado mientras estaba en WAR), sin embargo, entró en conflicto con la configuración log4j de Tomcat e impidió la salida de registros de la aplicación, lo que fue un factor decisivo ...
j pimmel

1
Esto suena como un problema de log4j más que cualquier otra cosa. Escríbame en forum.jolbox.com y lo ayudaré a localizarlo lo antes posible.
wwadge

3
1up, BoneCP es brillante. Cambiado de C3P0. ¡Incluso me permitió eliminar mi dependencia de log4jdbc-remix, porque permite el registro de sentencias fuera de la caja!
Subes

68
¡+1 por actualizar sobre algo que no escribiste siendo más rápido!
CorayThan

1
@AndrewScottEvans Probablemente sea mejor volver a v0.7.1
wwadge

16

Estaba teniendo problemas con DBCP cuando las conexiones se agotaban, así que probé c3p0. Iba a lanzar esto a producción pero luego comencé las pruebas de rendimiento. Encontré que c3p0 funcionó terriblemente. No pude configurarlo para que funcione bien. Lo encontré dos veces más lento que DBCP.

Luego probé la agrupación de conexiones Tomcat .

Esto fue el doble de rápido que c3p0 y solucionó otros problemas que tenía con DBCP. Pasé mucho tiempo investigando y probando los 3 grupos. Mi consejo si está implementando en Tomcat es utilizar el nuevo grupo JDBC de Tomcat.


14

Para el problema de la reconexión automática con DBCP, ¿alguien ha intentado usar los siguientes 2 parámetros de configuración?

validationQuery="Some Query"

testOnBorrow=true

En cuanto a la documentación ,testOnBorrow tiene un valor predeterminado true, por lo que si validationQueryestá definido, DBCP probará cada conexión antes de pasarla a la aplicación.
dma_k


12

He estado usando DBCP durante un par de años ahora en producción. Es estable, sobrevive al reinicio del servidor DB. Solo configúrelo correctamente. Solo requiere que se especifiquen algunos parámetros, así que no seas perezoso. Aquí hay un fragmento de nuestro código de producción del sistema que enumera los parámetros que configuramos explícitamente para que funcione:

DriverAdapterCPDS driverAdapterCPDS = new DriverAdapterCPDS();
driverAdapterCPDS.setUrl(dataSourceProperties.getProperty("url"));
driverAdapterCPDS.setUser(dataSourceProperties.getProperty("username"));
driverAdapterCPDS.setPassword(dataSourceProperties.getProperty("password"));
driverAdapterCPDS.setDriver(dataSourceProperties.getProperty("driverClass"));

driverAdapterCPDS.setMaxActive(Integer.valueOf(dataSourceProperties.getProperty("maxActive")));
driverAdapterCPDS.setMaxIdle(Integer.valueOf(dataSourceProperties.getProperty("maxIdle")));
driverAdapterCPDS.setPoolPreparedStatements(Boolean.valueOf(dataSourceProperties.getProperty("poolPreparedStatements")));

SharedPoolDataSource poolDataSource = new SharedPoolDataSource();
poolDataSource.setConnectionPoolDataSource(driverAdapterCPDS);
poolDataSource.setMaxWait(Integer.valueOf(dataSourceProperties.getProperty("maxWait")));
poolDataSource.setDefaultTransactionIsolation(Integer.valueOf(dataSourceProperties.getProperty("defaultTransactionIsolation")));
poolDataSource.setDefaultReadOnly(Boolean.valueOf(dataSourceProperties.getProperty("defaultReadOnly")));
poolDataSource.setTestOnBorrow(Boolean.valueOf(dataSourceProperties.getProperty("testOnBorrow")));
poolDataSource.setValidationQuery("SELECT 0");

8

Aquí hay algunos artículos que muestran que DBCP tiene un rendimiento significativamente mayor que C3P0 o Proxool. También en mi propia experiencia, c3p0 tiene algunas características agradables, como la agrupación de sentencias preparada y es más configurable que DBCP, pero DBCP es claramente más rápido en cualquier entorno en el que lo haya usado.

Diferencia entre dbcp y c3p0? ¡Absolutamente nada! (Un blog de desarrolladores de Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Consulte también el artículo JavaTech "Showdown de Pool de conexiones" en los comentarios en la publicación del blog.


44
más rápido en entornos de un solo subproceso, tal vez, con errores y no estable y simplemente roto en cualquier otro lugar

7

Otra alternativa, Proxool, se menciona en este artículo .

Es posible que pueda descubrir por qué Hibernate agrupa c3p0 para su implementación predeterminada del grupo de conexiones.


7

Lamentablemente, todos están desactualizados. DBCP se ha actualizado un poco recientemente, los otros dos tienen 2-3 años, con muchos errores pendientes.


Eso es cierto: la última versión de C3PO (una versión preliminar 0.9) es de mayo de 2007. La última versión de Proxool (versión preliminar 0.9) es de agosto de 2008. La última versión de DBCP también es de abril de 2007, pero al menos es una versión 1.2 estable. ¿Hay algo realmente mantenido por ahí?
Guss

44
Para ser justos, estos no son grandes proyectos, por lo que debe esperar cada vez menos actualizaciones en C3P0 / DBCP y pasar el tiempo.
wwadge

7

Dbcp está listo para producción si está configurado correctamente.

Por ejemplo, se utiliza en un sitio web de comercio de 350000 visitantes / día y con grupos de 200 conexiones.

Maneja muy bien los tiempos de espera siempre que lo configure correctamente.

La versión 2 está en progreso y tiene antecedentes que la hacen confiable ya que se han abordado muchos problemas de producción.

Lo usamos para nuestra solución de servidor por lotes y ha estado ejecutando cientos de lotes que funcionan en millones de líneas en la base de datos.

Las pruebas de rendimiento ejecutadas por el grupo tomcat jdbc muestran que tiene un mejor rendimiento que cp30.


UBIK LOAD PACK: estamos utilizando DBCP 1.4 y nos encontramos con bloqueos constantes de nuestro único lote con 10000 registros. Estamos usando Spring Batch + JSR 352 y estamos pensando en cambiar a HikariCP. Cuando dice que cientos de lotes funcionan sin problemas, ¿quiere decir que funciona con DBCP 2.xo cualquier otra versión? Además, ¿te importaría compartir las configuraciones? Nuestra configuración es maxActive = 150, minIdle = 15, maxIdle = 75, initialSize = 15 pero no hemos visto que los bloqueos desaparezcan. No estamos utilizando validationQuery o testOnBorrow / testOnReturn. ¿Recomiendas usarlo?
Yogendra

4

Acabo de terminar perdiendo un día y medio con DBCP. Aunque estoy usando la última versión de DBCP, me encontré exactamente con los mismos problemas que j pimmel . No recomendaría DBCP en absoluto, especialmente es la habilidad de tirar conexiones fuera del grupo cuando el DB desaparece, su incapacidad para volver a conectarse cuando el DB regresa y su incapacidad para agregar dinámicamente objetos de conexión nuevamente al grupo (se cuelga para siempre una lectura de socket de E / S JDBCconnect posterior)

Me estoy cambiando a C3P0 ahora. Lo he usado en proyectos anteriores y funcionó y funcionó a las mil maravillas.


4

c3p0 es bueno cuando usamos proyectos de mutithreading. En nuestros proyectos, utilizamos simultáneamente múltiples ejecuciones de subprocesos mediante DBCP, luego obtuvimos un tiempo de espera de conexión si utilizamos más ejecuciones de subprocesos. Entonces fuimos con la configuración c3p0.


3

Una buena alternativa que es fácil de usar es DBPool .

"Una utilidad de agrupación de conexiones de bases de datos basada en Java, que admite la caducidad basada en el tiempo, el almacenamiento en caché de instrucciones, la validación de conexiones y la configuración sencilla mediante un administrador de agrupaciones".

http://www.snaq.net/java/DBPool/


Comparé DBPool vs BoneCP. DBPool sincroniza getConnection () entre otras cosas y es mucho más lento que BoneCP (ver: jolbox.com/forum/viewtopic.php?f=3&t=175 ).
wwadge

3

Nos encontramos con una situación en la que necesitábamos introducir un grupo de conexiones y teníamos 4 opciones frente a nosotros.

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

Realizamos algunas pruebas y comparaciones basadas en nuestros criterios y decidimos optar por HikariCP. Lea este artículo que explica por qué elegimos HikariCP.


1

Para implementar el C3P0 de la mejor manera, verifique esta respuesta

C3P0 :

Para aplicaciones empresariales, C3P0 es el mejor enfoque. C3P0 es una biblioteca fácil de usar para aumentar los controladores JDBC tradicionales (basados ​​en DriverManager) con DataSources enlazables JNDI, incluidos DataSources que implementan Connection and Statement Pooling, como se describe en la especificación jdbc3 y la extensión std jdbc2. C3P0 también manejó robustamente las desconexiones de DB y las reconexiones transparentes en el currículum, mientras que DBCP nunca recuperó las conexiones si el enlace se sacó de debajo.

Esta es la razón por la cual c3p0 y otros grupos de conexiones también tienen cachés de instrucciones preparadas: permite que el código de la aplicación evite lidiar con todo esto. Las declaraciones generalmente se mantienen en un grupo limitado de LRU, por lo que las declaraciones comunes reutilizan una instancia de PreparedStatement.

Peor aún, DBCP estaba devolviendo objetos de conexión a la aplicación para la que se había roto el transporte subyacente. Un caso de uso común para c3p0 es reemplazar la agrupación de conexiones DBCP estándar incluida con Apache Tomcat. Muchas veces, un programador se encontrará con una situación en la que las conexiones no se reciclan correctamente en el grupo de conexiones DBCP y c3p0 es un reemplazo valioso en este caso.

En las actualizaciones actuales, C3P0 tiene algunas características brillantes. esos se dan abajo:

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMinPoolSize();
dataSource.setMaxPoolSize();
dataSource.setMaxIdleTime();
dataSource.setMaxStatements();
dataSource.setMaxStatementsPerConnection();
dataSource.setMaxIdleTimeExcessConnections();

Aquí, el tamaño de grupo máximo y mínimo define los límites de conexión que significan la conexión mínima y máxima que tomará esta aplicación. MaxIdleTime()defina cuándo liberará la conexión inactiva.

DBCP :

Este enfoque también es bueno, pero tiene algunos inconvenientes, como el tiempo de espera de la conexión y la liberación de la conexión. C3P0 es bueno cuando estamos usando proyectos de mutithreading. En nuestros proyectos, utilizamos simultáneamente múltiples ejecuciones de subprocesos mediante DBCP, luego obtuvimos un tiempo de espera de conexión si utilizamos más ejecuciones de subprocesos. Entonces fuimos con la configuración c3p0. No recomendaría DBCP en absoluto, especialmente es la habilidad de tirar conexiones fuera del grupo cuando el DB desaparece, su incapacidad para volver a conectarse cuando el DB regresa y su incapacidad para agregar dinámicamente objetos de conexión nuevamente al grupo (se cuelga para siempre una lectura de socket de E / S JDBCconnect posterior)

Gracias :)


1

mi recomendación es

hikari> druida> UCP> c3p0> DBCP

Se basa en lo que he probado: 20190202, en mi entorno de prueba local (4GB mac / mysql en docker / pool minSize = 1, maxSize = 8), hikari puede servir 1024 hilos x 1024 veces para obtener conexiones, tiempo promedio para cada hilo terminar es de 1 o 2 millones de segundos, mientras que c3p0 solo puede servir 256 hilos x 1024 veces y el tiempo promedio para cada hilo ya es de 21 millones de segundos. (512 hilos fallados).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.