Verbindungspooling-Optionen mit JDBC: DBCP vs C3P0


312

Was ist die beste verfügbare Verbindungspoolbibliothek für Java / JDBC?

Ich betrachte die 2 Hauptkandidaten (kostenlos / Open Source):

Ich habe in Blogs und anderen Foren viel darüber gelesen, konnte aber keine Entscheidung treffen.

Gibt es relevante Alternativen zu diesen beiden?

Antworten:


181

DBCP ist veraltet und nicht produktionsfähig. Vor einiger Zeit haben wir eine interne Analyse der beiden durchgeführt und eine Testvorrichtung erstellt, die eine Last und Parallelität zwischen den beiden erzeugt, um ihre Eignung unter realen Bedingungen zu beurteilen.

DBCP generierte konsequent Ausnahmen in unserer Testanwendung und bemühte sich, Leistungsniveaus zu erreichen, die C3P0 ohne Ausnahmen mehr als verarbeiten konnte.

C3P0 handhabte auch DB-Trennungen und transparente Wiederverbindungen bei Wiederaufnahme robust, während DBCP Verbindungen nie wiederherstellte, wenn die Verbindung darunter herausgenommen wurde. Schlimmer noch, DBCP gab Verbindungsobjekte an die Anwendung zurück, für die der zugrunde liegende Transport unterbrochen wurde.

Seitdem haben wir C3P0 in 4 großen Web-Apps für Endverbraucher verwendet und haben nie zurückgeschaut.

UPDATE: Es stellt sich heraus, dass die Apache Commons-Leute nach vielen Jahren im Regal DBCP aus dem Ruhezustand genommen haben und es sich nun wieder um ein aktiv entwickeltes Projekt handelt. Daher ist mein ursprünglicher Beitrag möglicherweise veraltet.

Abgesehen davon habe ich die Leistung dieser neuen aktualisierten Bibliothek noch nicht erlebt und noch nie davon gehört, dass sie in einem neueren App-Framework de facto vorhanden ist.


2
Vielen Dank! Wie wäre es mit der vorgeschlagenen Proxool-Alternative? Die aktuelle Version von Hibernate enthält sowohl c3p0 als auch Proxool.
Dema

Wir haben Proxool noch nicht ausprobiert, aber ich werde es mir jetzt sicher
ansehen

5
c3p0 hat einige Nachteile. Manchmal werden Verbindungsspitzen nicht verarbeitet.
Janning

3
Seit 4 Jahren, als Sie diese Antwort zum ersten Mal veröffentlicht haben, haben sich die Dinge stark verändert. Können Sie nach Möglichkeit ein Update hinzufügen, das das aktuelle Szenario teilt?
Rajat Gupta

13
Ich kann HikariCP nur empfehlen , aber dann habe ich geholfen, es zu schreiben.
Brettw

177

Ich lade Sie ein, BoneCP auszuprobieren - es ist kostenlos, Open Source und schneller als die verfügbaren Alternativen (siehe Benchmark-Abschnitt).

Haftungsausschluss: Ich bin der Autor, also könnte man sagen, dass ich voreingenommen bin :-)

UPDATE: Ab März 2010 immer noch rund 35% schneller als der neu geschriebene Apache DBCP-Pool ("tomcat jdbc"). Siehe dynamischer Benchmark-Link im Benchmark-Abschnitt.

Update Nr. 2: (13. Dezember) Nach 4 Jahren an der Spitze gibt es jetzt einen viel schnelleren Konkurrenten: https://github.com/brettwooldridge/HikariCP

Update Nr. 3: (14. September) Bitte beachten Sie, dass BoneCP zu diesem Zeitpunkt veraltet ist. Empfehlen Sie den Wechsel zu HikariCP .

Update Nr. 4: (15. April) - Ich besitze die Domain jolbox.com nicht mehr


1
Würde wirklich gerne eine Fehlerbehebung mit BoneCP als Tomcat-Datenquelle erhalten. Das Hauptproblem dabei war, dass BoneCP-Klassen in Tomcats lib-Verzeichnis sowie die Klassen log4j und google erforderlich waren. Dadurch funktionierten die Verbindungspools - (es war in WAR nicht funktioniert) - jedoch widersprach es der log4j-Einstellung von Tomcat und verhinderte überhaupt eine Protokollausgabe der Anwendung, die ein Dealbreaker war ...
j pimmel

1
Dies klingt vor allem nach einem log4j-Problem. Schreiben Sie mir auf forum.jolbox.com und ich werde Ihnen helfen, es so schnell wie möglich zu finden.
wwadge

3
1up, BoneCP ist brillant. Von C3P0 gewechselt. Es erlaubte mir sogar, meine Abhängigkeit von log4jdbc-remix zu entfernen, da es die sofortige Protokollierung von Anweisungen ermöglicht!
Subes

68
+1 für die Aktualisierung von etwas, das Sie nicht geschrieben haben, schneller!
CorayThan

1
@ AndrewScottEvans Wahrscheinlich am besten, um zu v0.7.1 zurückzukehren
wwadge

16

Ich hatte Probleme mit DBCP, als die Verbindung unterbrochen wurde, also habe ich c3p0 getestet. Ich wollte dies für die Produktion freigeben, begann dann aber mit Leistungstests. Ich fand, dass c3p0 eine schreckliche Leistung erbrachte. Ich konnte es nicht so konfigurieren, dass es überhaupt gut funktioniert. Ich fand es doppelt so langsam wie DBCP.

Ich habe dann versucht, das Tomcat-Verbindungspooling durchzuführen .

Dies war doppelt so schnell wie c3p0 und behebt andere Probleme, die ich mit DBCP hatte. Ich habe viel Zeit damit verbracht, die 3 Pools zu untersuchen und zu testen. Mein Rat, wenn Sie auf Tomcat bereitstellen, ist die Verwendung des neuen Tomcat-JDBC-Pools.


14

Hat jemand versucht, die folgenden 2 Konfigurationsparameter für das Problem der automatischen erneuten Verbindung mit DBCP zu verwenden?

validationQuery="Some Query"

testOnBorrow=true

In Bezug auf Dokumentation , testOnBorrowhat Standardwert true, also wenn validationQueryDBCP jede Verbindung testen wird definiert , bevor es auf die Anwendung übergeben wird.
dma_k


12

Ich benutze DBCP seit ein paar Jahren in der Produktion. Es ist stabil und überlebt den Neustart des DB-Servers. Konfigurieren Sie es einfach richtig. Es müssen nur eine Handvoll Parameter angegeben werden, seien Sie also nicht faul. Hier ist ein Ausschnitt aus unserem Systemproduktionscode, der Parameter auflistet, die wir explizit festgelegt haben, damit es funktioniert:

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

Hier sind einige Artikel, die zeigen, dass DBCP eine deutlich höhere Leistung als C3P0 oder Proxool aufweist. Auch nach meiner eigenen Erfahrung hat c3p0 einige nette Funktionen, wie das vorbereitete Anweisungspooling, und ist konfigurierbarer als DBCP, aber DBCP ist in jeder Umgebung, in der ich es verwendet habe, deutlich schneller.

Unterschied zwischen dbcp und c3p0? Absolut gar nichts! (Ein Sakai-Entwicklerblog) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Siehe auch den JavaTech-Artikel "Connection Pool Showdown" in den Kommentaren zum Blog-Beitrag.


4
In Umgebungen mit einem Thread schneller, vielleicht fehlerhaft und instabil und einfach irgendwo anders kaputt.

7

Eine andere Alternative, Proxool, wird in diesem Artikel erwähnt .

Möglicherweise können Sie herausfinden, warum Hibernate c3p0 für die Standardimplementierung des Verbindungspools bündelt.


7

Leider sind sie alle veraltet. DBCP wurde kürzlich ein wenig aktualisiert, die anderen beiden sind 2-3 Jahre alt und haben viele herausragende Fehler.


Das ist wahr - die letzte Version von C3PO (eine Vorabversion von 0,9) ist von Mai 2007. Die neueste Version von Proxool (eine Vorabversion von 0,9) ist von August 2008. Die letzte Version von DBCP ist ebenfalls von April 2007, aber Zumindest ist es eine stabile Version 1.2. Gibt es da draußen tatsächlich etwas?
Guss

4
Um fair zu sein, sind dies keine großen Projekte, daher sollten Sie immer weniger Updates in C3P0 / DBCP erwarten und die Zeit vergeht.
wwadge

7

Dbcp ist produktionsbereit, wenn es richtig konfiguriert ist.

Es wird beispielsweise auf einer Commerce-Website mit 350000 Besuchern pro Tag und mit Pools von 200 Verbindungen verwendet.

Timeouts werden sehr gut verarbeitet, sofern Sie sie richtig konfigurieren.

Version 2 ist im Gange und hat einen Hintergrund, der sie zuverlässig macht, da viele Produktionsprobleme behoben wurden.

Wir verwenden es für unsere Batch-Server-Lösung und es wurden Hunderte von Batches ausgeführt, die auf Millionen von Zeilen in der Datenbank funktionieren.

Leistungstests, die vom Tomcat JDBC-Pool ausgeführt werden, zeigen, dass die Leistung besser ist als bei cp30.


UBIK LOAD PACK - Wir verwenden DBCP 1.4 und stoßen auf konstante Hänge unseres einzelnen Batches mit 10000 Datensätzen. Wir verwenden Spring Batch + JSR 352 und denken darüber nach, auf HikariCP umzusteigen. Wenn Sie sagen, dass Hunderte von Stapeln reibungslos laufen, meinen Sie damit, dass sie mit DBCP 2.x oder einer anderen Version ausgeführt werden? Würde es Ihnen auch etwas ausmachen, die Konfigurationen zu teilen? Unsere Konfiguration ist maxActive = 150, minIdle = 15, maxIdle = 75, initialSize = 15, aber es wurden keine Hänge entfernt. Wir verwenden keine validationQuery oder testOnBorrow / testOnReturn. Empfehlen Sie die Verwendung?
Yogendra

4

Ich bin gerade damit fertig, anderthalb Tage mit DBCP zu verschwenden. Obwohl ich die neueste DBCP-Version verwende, habe ich genau die gleichen Probleme wie j pimmel . Ich würde DBCP überhaupt nicht empfehlen, insbesondere wenn es darum geht, Verbindungen aus dem Pool zu werfen, wenn die Datenbank nicht mehr verfügbar ist, wenn es nicht möglich ist, die Verbindung wiederherzustellen, wenn die Datenbank zurückkommt, und wenn es nicht möglich ist, Verbindungsobjekte dynamisch wieder in den Pool aufzunehmen (es bleibt für immer hängen ein Post-JDBCconnect-E / A-Socket gelesen)

Ich wechsle jetzt zu C3P0. Ich habe das in früheren Projekten verwendet und es hat wie ein Zauber funktioniert und funktioniert.


4

c3p0 ist gut, wenn wir Mutithreading-Projekte verwenden. In unseren Projekten haben wir mithilfe von DBCP gleichzeitig mehrere Thread-Ausführungen verwendet. Wenn wir mehr Thread-Ausführungen verwendet haben, ist das Verbindungszeitlimit abgelaufen. Also haben wir uns für die c3p0-Konfiguration entschieden.


3

Eine gute Alternative, die einfach zu bedienen ist, ist DBPool .

"Ein Java-basiertes Dienstprogramm zum Poolen von Datenbankverbindungen, das zeitbasiertes Ablaufen, Zwischenspeichern von Anweisungen, Verbindungsüberprüfung und einfache Konfiguration mithilfe eines Poolmanagers unterstützt."

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


Ich habe DBPool gegen BoneCP verglichen. DBPool synchronisiert getConnection () unter anderem und ist weitaus langsamer als BoneCP (siehe: jolbox.com/forum/viewtopic.php?f=3&t=175 ).
wwadge

3

Wir stießen auf eine Situation, in der wir einen Verbindungspool einführen mussten, und wir hatten 4 Optionen vor uns.

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

Wir haben einige Tests und Vergleiche anhand unserer Kriterien durchgeführt und uns für HikariCP entschieden. Lesen Sie diesen Artikel, in dem erklärt wird, warum wir uns für HikariCP entschieden haben.


1

Um den C3P0 optimal zu implementieren, überprüfen Sie diese Antwort

C3P0 :

Für Unternehmensanwendungen ist C3P0 der beste Ansatz. C3P0 ist eine benutzerfreundliche Bibliothek zum Erweitern traditioneller (DriverManager-basierter) JDBC-Treiber mit JNDI-bindbaren DataSources, einschließlich DataSources, die Connection and Statement Pooling implementieren, wie in der jdbc3-Spezifikation und der jdbc2-Standarderweiterung beschrieben. C3P0 handhabte auch DB-Trennungen und transparente Wiederverbindungen bei Wiederaufnahme robust, während DBCP Verbindungen nie wiederherstellte, wenn die Verbindung darunter herausgenommen wurde.

Aus diesem Grund haben c3p0 und andere Verbindungspools auch Anweisungscaches vorbereitet. Dadurch kann der Anwendungscode vermeiden, sich mit all dem zu befassen. Die Anweisungen werden normalerweise in einem begrenzten LRU-Pool gespeichert, sodass allgemeine Anweisungen eine PreparedStatement-Instanz wiederverwenden.

Schlimmer noch, DBCP gab Verbindungsobjekte an die Anwendung zurück, für die der zugrunde liegende Transport unterbrochen wurde. Ein häufiger Anwendungsfall für c3p0 besteht darin, das in Apache Tomcat enthaltene Standard-DBCP-Verbindungspooling zu ersetzen. Oft stößt ein Programmierer auf eine Situation, in der Verbindungen im DBCP-Verbindungspool nicht korrekt recycelt werden und c3p0 in diesem Fall ein wertvoller Ersatz ist.

In aktuellen Updates hat C3P0 einige brillante Funktionen. diese sind unten angegeben:

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

Hier definieren die Poolgrößen max und min die Verbindungsgrenzen, dh wie die minimale und maximale Verbindung diese Anwendung nimmt. MaxIdleTime()Definieren Sie, wann die Leerlaufverbindung freigegeben wird.

DBCP :

Dieser Ansatz ist ebenfalls gut, weist jedoch einige Nachteile auf, wie z. B. Verbindungszeitlimit und Verbindungsfreigabe. C3P0 ist gut, wenn wir Mutithreading-Projekte verwenden. In unseren Projekten haben wir mehrere Thread-Ausführungen gleichzeitig mithilfe von DBCP verwendet. Wenn wir mehr Thread-Ausführungen verwendet haben, haben wir ein Verbindungszeitlimit. Also haben wir uns für die c3p0-Konfiguration entschieden. Ich würde DBCP überhaupt nicht empfehlen, insbesondere wenn es darum geht, Verbindungen aus dem Pool zu werfen, wenn die Datenbank nicht mehr verfügbar ist, wenn es nicht möglich ist, die Verbindung wiederherzustellen, wenn die Datenbank zurückkommt, und wenn es nicht möglich ist, Verbindungsobjekte dynamisch wieder in den Pool aufzunehmen (es bleibt für immer hängen ein Post-JDBCconnect-E / A-Socket gelesen)

Vielen Dank :)


1

Meine Empfehlung ist

hikari> druide> UCP> c3p0> DBCP

Es basiert auf dem, was ich getestet habe - 20190202, in meiner lokalen Testumgebung (4 GB Mac / MySQL in Docker / Pool minSize = 1, maxSize = 8) kann Hikari 1024 Threads x 1024 Mal bedienen, um Verbindungen zu erhalten, durchschnittliche Zeit für jeden Thread Das Ende beträgt 1 oder 2 Millionen Sekunden, während c3p0 nur 256 Threads x 1024 Mal bedienen kann und die durchschnittliche Zeit für jeden Thread bereits 21 Millionen Sekunden beträgt. (512 Threads fehlgeschlagen).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.