java - org - Opciones de agrupación de conexiones con JDBC: DBCP vs C3P0
tomcat jdbc connection pool example (15)
Acabo de terminar de perder un día y medio con DBCP. A pesar de que estoy usando la última versión de DBCP, encontré exactamente los mismos problemas que hizo j pimmel . No recomendaría DBCP en absoluto, especialmente su habilidad para lanzar conexiones fuera de la agrupación cuando la DB desaparece, su incapacidad para volver a conectarse cuando la DB regresa y su incapacidad para agregar objetos de conexión dinámicamente a la agrupación (se cuelga para siempre un post JDBCconnect I / O socket leído)
Estoy cambiando a C3P0 ahora. Lo he usado en proyectos anteriores y funcionó y funcionó a la perfección.
¿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):
- Apache DBCP - http://commons.apache.org/dbcp/
- C3P0 - http://sourceforge.net/projects/c3p0
He leído mucho sobre ellos en blogs y otros foros, pero no pude tomar una decisión.
¿Hay alternativas relevantes para estos dos?
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 interesantes, como la agrupación de sentencias preparadas 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 de JavaTech "Connection Pool Showdown" en los comentarios en la publicación del blog.
DBCP está fuera de fecha y no de grado de producción. Hace algún tiempo, realizamos un análisis interno de los dos, creando un dispositivo de prueba que generó carga y concurrencia contra los dos para evaluar su idoneidad en condiciones de la vida real.
DBCP generó consistentemente excepciones en nuestra aplicación de prueba y luchó para alcanzar niveles de rendimiento que C3P0 era más que capaz de manejar sin excepciones.
C3P0 también manejó de forma robusta las desconexiones de la base de datos y las reconexiones transparentes en la reanudación, mientras que la DBCP nunca recuperó las conexiones si el enlace se eliminó de debajo. Peor aún, DBCP estaba devolviendo objetos de Conexión a la aplicación para la cual se había interrumpido el transporte subyacente.
Desde entonces, hemos utilizado C3P0 en 4 de las principales aplicaciones web de gran carga para el consumidor 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 http://commons.apache.org/dbcp/ y ahora es, una vez más, un proyecto desarrollado activamente. Por lo tanto, mi publicación original puede estar desactualizada.
Dicho esto, aún no he experimentado el rendimiento de esta nueva biblioteca mejorada, ni he oído hablar de que esté de facto en ningún marco de aplicación reciente.
Dbcp está listo para la producción si está configurado correctamente.
Se utiliza, por ejemplo, en un sitio web comercial de 350000 visitantes / día y con grupos de 200 conexiones.
Maneja muy bien los tiempos de espera siempre que lo configures correctamente.
La versión 2 está en progreso y tiene un fondo que la hace confiable ya que muchos problemas de producción se han abordado.
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 realizadas por el grupo tomcat jdbc muestran que tiene un mejor rendimiento que cp30.
Estaba teniendo problemas con DBCP cuando las conexiones se agotan, así que probé c3p0. Iba a lanzar esto a producción pero luego comencé a realizar pruebas de rendimiento. Encontré que c3p0 realizó terriblemente. No pude configurarlo para funcionar bien en absoluto. Lo encontré dos veces más lento que DBCP.
Entonces probé la agrupación de conexiones Tomcat .
Esto fue el doble de rápido que c3p0 y solucionó otros problemas que estaba teniendo con DBCP. Pasé mucho tiempo investigando y probando los 3 grupos. Mi consejo si está implementando en Tomcat es usar el nuevo grupo de JDBC de Tomcat.
He estado utilizando DBCP durante un par de años en producción. Es estable, sobrevive al reinicio del servidor DB. Sólo configúralo correctamente. Solo requiere un puñado de parámetros para ser especificado, 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");
Lamentablemente todos están desactualizados. DBCP se ha actualizado un poco recientemente, los otros dos tienen 2-3 años de antigüedad, con muchos errores sobresalientes.
Lo invito a probar BoneCP : es gratuito, 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, así que se podría decir que soy parcial :-)
ACTUALIZACIÓN: A partir de marzo de 2010, todavía un 35% más rápido que el nuevo grupo Apache DBCP ("tomcat jdbc") reescrito. Ver enlace de referencia dinámico en la sección de referencia.
Actualización # 2: (diciembre ''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 # 3: (Sep ''14) Considere que BoneCP está en desuso en este momento, recomiendo cambiar a HikariCP .
Actualización # 4: (abril ''15) - Ya no soy dueño del dominio jolbox.com, pero el nuevo propietario ha mantenido el contenido anterior, así que ten cuidado.
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
Llevamos a cabo algunas pruebas y comparaciones basadas en nuestros criterios y decidimos optar por HikariCP. Lee este artículo que explica por qué elegimos HikariCP.
Otra alternativa es https://github.com/brettwooldridge/HikariCP .
Aquí está la comparación benchmark
Otra alternativa, Proxool, se menciona en este artículo .
Es posible que pueda averiguar por qué Hibernate agrupa c3p0 para su implementación de conjunto de conexiones predeterminado.
Para el problema de la reconexión automática con DBCP, ¿se ha intentado usar los siguientes 2 parámetros de configuración?
validationQuery="Some Query"
testOnBorrow=true
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 a JNDI, incluidos los DataSources que implementan Connection y Statement Pooling, como se describe en la especificación jdbc3 y la extensión std jdbc2. C3P0 también manejó de forma robusta las desconexiones de la base de datos y las reconexiones transparentes en la reanudación, mientras que la DBCP nunca recuperó las conexiones si el enlace se eliminó de debajo.
Por lo tanto, esta es la razón por la que c3p0 y otras agrupaciones de conexiones también han preparado cachés de instrucciones: permite que el código de la aplicación evite hacer frente a todo esto. Las declaraciones generalmente se guardan 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 cual se había interrumpido 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. los que se dan a continuación:
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 definen los límites de conexión, lo que significa la conexión mínima y máxima que tomará esta aplicación. MaxIdleTime()
define cuándo se 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 utilizando DBCP, luego obtuvimos un tiempo de espera de conexión si utilizamos más ejecuciones de subprocesos. Así que nos fuimos con la configuración c3p0. No recomendaría DBCP en absoluto, especialmente su habilidad para lanzar conexiones fuera de la agrupación cuando la DB desaparece, su incapacidad para volver a conectarse cuando la DB regresa y su incapacidad para agregar objetos de conexión dinámicamente a la agrupación (se cuelga para siempre un post JDBCconnect I / O socket leído)
Gracias :)
Una buena alternativa que es fácil de usar es DBPool .
"Una utilidad de agrupación de conexiones de base de datos basada en Java, que admite la caducidad basada en el tiempo, el almacenamiento en caché de sentencias, la validación de la conexión y la fácil configuración mediante un administrador de agrupaciones".
c3p0 es bueno cuando estamos usando proyectos de mutithreading. En nuestros proyectos, utilizamos simultáneamente múltiples ejecuciones de subprocesos utilizando DBCP, luego obtuvimos un tiempo de espera de conexión si utilizamos más ejecuciones de subprocesos. Así que nos fuimos con la configuración c3p0.