Options de regroupement de connexions avec JDBC: DBCP vs C3P0

312

Quelle est la meilleure bibliothèque de regroupement de connexions disponible pour Java / JDBC?

Je considère les 2 principaux candidats (gratuits / open-source):

J'ai beaucoup lu à leur sujet dans les blogs et autres forums, mais je n'ai pas pu prendre de décision.

Existe-t-il des alternatives pertinentes à ces deux?

Dema
la source

Réponses:

181

Le DBCP est obsolète et n'est pas de qualité production. Il y a quelque temps, nous avons effectué une analyse interne des deux, créant un dispositif de test qui a généré une charge et une concurrence par rapport aux deux pour évaluer leur adéquation dans des conditions réelles.

DBCP a systématiquement généré des exceptions dans notre application de test et a eu du mal à atteindre des niveaux de performance que C3P0 était plus que capable de gérer sans aucune exception.

C3P0 a également géré de manière robuste les déconnexions de base de données et les reconnexions transparentes lors de la reprise, tandis que DBCP n'a jamais récupéré les connexions si la liaison était supprimée en dessous. Pire encore, DBCP renvoyait des objets Connection à l'application pour laquelle le transport sous-jacent s'était rompu.

Depuis lors, nous avons utilisé C3P0 dans 4 principales applications Web grand public et n'avons jamais regardé en arrière.

MISE À JOUR: Il s'avère qu'après de nombreuses années passées sur une étagère, les gens d'Apache Commons ont sorti le DBCP de la dormance et c'est maintenant, encore une fois, un projet activement développé. Ainsi, mon message d'origine peut être obsolète.

Cela étant dit, je n'ai pas encore expérimenté les performances de cette nouvelle bibliothèque mise à niveau, ni entendu qu'elle soit de facto dans un cadre d'application récent, pour l'instant.

j pimmel
la source
2
Merci! Que diriez-vous de l'alternative Proxool suggérée? La version actuelle d'Hibernate est livrée avec c3p0 et Proxool.
Dema
Nous n'avons pas essayé Proxool mais je vais être sûr de le vérifier maintenant :)
j pimmel
5
c3p0 présente certains inconvénients. il échoue parfois à gérer les pics de connexion.
Janning
3
les choses ont beaucoup changé depuis 4 ans lorsque vous avez publié cette réponse pour la première fois, pourriez-vous ajouter une mise à jour partageant le scénario actuel, si possible?
Rajat Gupta
13
Je recommande fortement HikariCP , mais j'ai ensuite aidé à l'écrire.
brettw
177

Je vous invite à essayer BoneCP - c'est gratuit, open source et plus rapide que les alternatives disponibles (voir la section benchmark).

Avertissement: je suis l'auteur, vous pouvez donc dire que je suis partial :-)

MISE À JOUR: En mars 2010, toujours environ 35% plus rapide que le nouveau pool Apache DBCP ("tomcat jdbc") réécrit. Voir le lien de référence dynamique dans la section de référence.

Mise à jour # 2: (décembre '13) Après 4 ans au sommet, il y a maintenant un concurrent beaucoup plus rapide: https://github.com/brettwooldridge/HikariCP

Mise à jour # 3: (Sep '14) Veuillez considérer BoneCP comme obsolète à ce stade, recommandez de passer à HikariCP .

Mise à jour # 4: (avril '15) - Je ne possède plus le domaine jolbox.com

wwadge
la source
1
J'aimerais vraiment obtenir un dépannage en utilisant BoneCP comme source de données Tomcat. Le principal problème que j'ai eu avec cela était qu'il nécessitait les classes BoneCP dans le répertoire lib de tomcat, ainsi que les classes log4j et google. Faire cela a fait fonctionner les pools de connexions - (cela n'avait pas fonctionné pendant la guerre) - mais cela était en conflit avec le paramètre log4j de Tomcat et empêchait toute sortie de journal de l'application, qui était un dealbreaker ...
j pimmel
1
Cela ressemble à un problème de log4j plus que toute autre chose. Envoyez-moi une ligne sur forum.jolbox.com et je vous aiderai à le retrouver dès que possible.
wwadge
3
1up, BoneCP est génial. Passé de C3P0. Cela m'a même permis de supprimer ma dépendance à log4jdbc-remix, car cela permet de se déconnecter des instructions de la boîte!
subes
68
+1 pour la mise à jour de quelque chose que vous n'avez pas écrit étant plus rapide!
CorayThan
1
@AndrewScottEvans Il est probablement préférable de revenir à la version 0.7.1
wwadge
16

J'avais des problèmes avec DBCP lorsque les connexions expirent, j'ai donc testé c3p0. J'allais mettre cela en production mais j'ai ensuite commencé les tests de performances. J'ai trouvé que c3p0 fonctionnait terriblement. Je n'ai pas pu le configurer pour qu'il fonctionne bien du tout. Je l'ai trouvé deux fois plus lent que DBCP.

J'ai ensuite essayé le pool de connexions Tomcat .

C'était deux fois plus rapide que c3p0 et corrigeait d'autres problèmes que j'avais avec DBCP. J'ai passé beaucoup de temps à enquêter et à tester les 3 pools. Mon conseil si vous déployez sur Tomcat est d'utiliser le nouveau pool Tomcat JDBC.

user542651
la source
14

Pour le problème de reconnexion automatique avec DBCP, quelqu'un a-t-il essayé d'utiliser les 2 paramètres de configuration suivants?

validationQuery="Some Query"

testOnBorrow=true
Brandon Teo
la source
Quant à la documentation , testOnBorrowa une valeur par défaut true, donc si elle validationQueryest définie, DBCP testera chaque connexion avant qu'elle ne soit transmise à l'application.
dma_k
12

J'utilise DBCP depuis quelques années maintenant en production. Il est stable et survit au redémarrage du serveur DB. Il suffit de le configurer correctement. Il ne nécessite que quelques paramètres à spécifier, alors ne soyez pas paresseux. Voici un extrait de notre code de production système qui répertorie les paramètres que nous avons explicitement définis pour le faire fonctionner:

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");
oᴉɹǝɥɔ
la source
8

Voici quelques articles qui montrent que DBCP a des performances nettement supérieures à C3P0 ou Proxool. De plus, d'après ma propre expérience, c3p0 a de belles fonctionnalités, comme le pool d'instructions préparé et est plus configurable que DBCP, mais DBCP est clairement plus rapide dans tous les environnements dans lesquels je l'ai utilisé.

Différence entre dbcp et c3p0? Absolument rien! (Un blog des développeurs Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Voir aussi l'article de JavaTech "Connection Pool Showdown" dans les commentaires sur le blog.

Divyesh Kanzariya
la source
4
plus rapide dans les environnements à thread unique, peut-être, bogué et instable et tout simplement cassé ailleurs.
7

Une autre alternative, Proxool, est mentionnée dans cet article .

Vous pourrez peut-être découvrir pourquoi Hibernate regroupe c3p0 pour son implémentation de pool de connexions par défaut?

boîte à outils
la source
7

Malheureusement, ils sont tous dépassés. DBCP a été mis à jour un peu récemment, les deux autres ont 2-3 ans, avec de nombreux bugs en suspens.


la source
C'est vrai - la dernière version de C3PO (une pré-version 0.9) date de mai 2007. La dernière version de Proxool (une pré-version 0.9) date d'août 2008. La dernière version de DBCP date également d'avril 2007, mais au moins c'est une version 1.2 stable. Y a-t-il vraiment quelque chose qui existe?
Guss
4
Pour être honnête, ce ne sont pas de grands projets, vous devez donc vous attendre à de moins en moins de mises à jour dans C3P0 / DBCP et le temps passe.
wwadge
7

Dbcp est prêt pour la production s'il est correctement configuré.

Il est par exemple utilisé sur un site de commerce de 350000 visiteurs / jour et avec des pools de 200 connexions.

Il gère très bien les délais d'attente à condition de le configurer correctement.

La version 2 est en cours de développement et a un fond qui la rend fiable car de nombreux problèmes de production ont été résolus.

Nous l'utilisons pour notre solution de serveur par lots et il a exécuté des centaines de lots qui fonctionnent sur des millions de lignes dans la base de données.

Les tests de performances exécutés par tomcat jdbc pool montrent qu'il a de meilleures performances que cp30.

UBIK LOAD PACK
la source
UBIK LOAD PACK - Nous utilisons DBCP 1.4 et exécutons des blocages constants de notre lot unique avec 10000 enregistrements. Nous utilisons Spring Batch + JSR 352 et pensons passer à HikariCP. Lorsque vous dites que des centaines de lots fonctionnent correctement, voulez-vous dire que cela fonctionne avec DBCP 2.x ou toute autre version? Pourriez-vous également partager les configurations? Notre configuration est maxActive = 150, minIdle = 15, maxIdle = 75, initialSize = 15 mais nous n'avons pas vu les blocages disparaître. Nous n'utilisons aucune validationQuery ou testOnBorrow / testOnReturn. Recommandez-vous de l'utiliser?
Yogendra
4

Je viens de perdre un jour et demi avec le DBCP. Même si j'utilise la dernière version de DBCP, j'ai rencontré exactement les mêmes problèmes que j pimmel . Je ne recommanderais pas du tout DBCP, en particulier son talent de jeter des connexions hors du pool lorsque la base de données disparaît, son incapacité à se reconnecter lorsque la base de données revient et son incapacité à ajouter dynamiquement des objets de connexion dans le pool (il se bloque pour toujours sur lecture d'un socket d'E / S JDBCconnect)

Je passe maintenant au C3P0. Je l'ai utilisé dans des projets précédents et cela a fonctionné et a fonctionné comme un charme.

Larry H
la source
4

c3p0 est bon lorsque nous utilisons des projets de mutithreading. Dans nos projets, nous avons utilisé simultanément plusieurs exécutions de threads en utilisant DBCP, puis nous avons obtenu un délai d'expiration de connexion si nous avons utilisé plus d'exécutions de threads. Nous avons donc opté pour la configuration c3p0.

nns
la source
3

DBPool est une bonne alternative facile à utiliser .

"Un utilitaire de mise en commun des connexions de base de données Java, prenant en charge l'expiration basée sur le temps, la mise en cache des instructions, la validation de la connexion et une configuration facile à l'aide d'un gestionnaire de pool."

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

Soundlink
la source
J'ai comparé DBPool vs BoneCP. DBPool synchronise entre autres getConnection () et est beaucoup plus lent que BoneCP (voir: jolbox.com/forum/viewtopic.php?f=3&t=175 ).
wwadge
3

Nous sommes tombés sur une situation où nous devions introduire un pool de connexions et nous avions 4 options devant nous.

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

Nous avons effectué quelques tests et comparaisons sur la base de nos critères et avons décidé d'opter pour HikariCP. Lisez cet article qui explique pourquoi nous avons choisi HikariCP.

Jeevan Patil
la source
1

Pour implémenter le C3P0 de la meilleure façon, vérifiez cette réponse

C3P0 :

Pour les applications d'entreprise, C3P0 est la meilleure approche. C3P0 est une bibliothèque facile à utiliser pour étendre les pilotes JDBC traditionnels (basés sur DriverManager) avec des DataSources pouvant être liées par JNDI, y compris des DataSources qui implémentent la connexion et le pool d'instructions, comme décrit par l'extension jdbc3 spec et jdbc2 std. C3P0 a également géré de manière robuste les déconnexions de base de données et les reconnexions transparentes lors de la reprise, tandis que DBCP n'a jamais récupéré les connexions si la liaison était supprimée en dessous.

C'est pourquoi c3p0 et d'autres pools de connexions ont également préparé des caches d'instructions - cela permet au code d'application d'éviter de traiter tout cela. Les instructions sont généralement conservées dans un pool LRU limité, donc les instructions courantes réutilisent une instance PreparedStatement.

Pire encore, DBCP renvoyait des objets Connection à l'application pour laquelle le transport sous-jacent s'était rompu. Un cas d'utilisation courant pour c3p0 est de remplacer le pool de connexions DBCP standard inclus avec Apache Tomcat. Souvent, un programmeur se retrouvera dans une situation où les connexions ne sont pas correctement recyclées dans le pool de connexions DBCP et c3p0 est un remplacement précieux dans ce cas.

Dans les mises à jour actuelles, C3P0 a des fonctionnalités brillantes. ceux-ci sont donnés ci-dessous:

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

Ici, les tailles de pool max et min définissent les limites de connexion, ce qui signifie la connexion minimale et maximale que cette application prendra. MaxIdleTime()définir quand il libérera la connexion inactive.

DBCP :

Cette approche est également bonne, mais présente certains inconvénients tels que le délai d'expiration de la connexion et la réactivation de la connexion. C3P0 est bon lorsque nous utilisons des projets de mutithreading. Dans nos projets, nous avons utilisé simultanément plusieurs exécutions de threads en utilisant DBCP, puis nous avons obtenu un délai d'expiration de connexion si nous avons utilisé plus d'exécutions de threads. Nous avons donc opté pour la configuration c3p0. Je ne recommanderais pas du tout DBCP, en particulier son talent de jeter des connexions hors du pool lorsque la base de données disparaît, son incapacité à se reconnecter lorsque la base de données revient et son incapacité à ajouter dynamiquement des objets de connexion dans le pool (il se bloque pour toujours sur lecture d'un socket d'E / S JDBCconnect)

Merci :)

Md. Sajedul Karim
la source
1

ma recommandation est

hikari> druide> UCP> c3p0> DBCP

Il est basé sur ce que j'ai testé - 20190202, dans mon environnement de test local (4 Go mac / mysql dans docker / pool minSize = 1, maxSize = 8), hikari peut servir 1024 threads x 1024 fois pour obtenir des connexions, temps moyen pour chaque thread terminer est de 1 ou 2 millions de secondes, alors que c3p0 ne peut servir que 256 threads x 1024 fois et le temps moyen pour chaque thread est déjà de 21 millions de secondes. (512 threads ont échoué).

Kyle Zhang
la source