Opzioni di pool di connessioni con JDBC: DBCP vs C3P0

Qual è la migliore libreria di pool di connessioni disponibile per Java / JDBC?

Sto considerando i 2 candidati principali (gratuito / open-source):

  • Apache DBCP – http://commons.apache.org/dbcp/
  • C3P0 – http://sourceforge.net/projects/c3p0

Ho letto molto su di loro nei blog e in altri forum, ma non ho potuto prendere una decisione.

Esistono alternative rilevanti a questi due?

DBCP non è aggiornato e non è di produzione. Qualche tempo fa abbiamo condotto un’analisi interna dei due, creando un dispositivo di prova che ha generato il carico e la concorrenza nei confronti dei due per valutare la loro idoneità in condizioni di vita reale.

DBCP generò costantemente delle eccezioni nella nostra applicazione di test e faticò a raggiungere livelli di prestazioni che C3P0 era più che capace di gestire senza eccezioni.

C3P0 ha inoltre gestito in modo robusto i disconnessioni DB e le riconnessioni trasparenti su CV, mentre DBCP non ha mai recuperato le connessioni se il collegamento è stato rimosso da sotto. Peggio ancora DBCP stava restituendo gli oggetti Connection all’applicazione per la quale il trasporto sottostante si era rotto.

Da allora abbiamo utilizzato C3P0 in 4 importanti app web per utenti di carichi pesanti e non ci siamo mai voltati indietro.

AGGIORNAMENTO: Si scopre che dopo molti anni di seduta su uno scaffale, la gente dei Comuni Apache ha tolto il DBCP dal letargo ed è ora, ancora una volta, un progetto triggersmente sviluppato. Quindi il mio post originale potrebbe non essere aggiornato.

Detto questo, non ho ancora sperimentato questa performance della nuova libreria aggiornata, né ne ho mai sentito parlare di fatto in qualsiasi framework di app recente, ancora.

Ti invito a provare BoneCP : è gratuito, open source e più veloce delle alternative disponibili (vedi la sezione benchmark).

Disclaimer: Sono l’autore per cui potresti dire che sono di parte 🙂

AGGIORNAMENTO: A marzo 2010, ancora circa il 35% più veloce del nuovo pool Apache DBCP (“tomcat jdbc”) riscritto. Vedi link benchmark dinamico nella sezione benchmark.

Aggiornamento n. 2: (Dic ’13) Dopo 4 anni in cima, ora c’è un concorrente molto più veloce: https://github.com/brettwooldridge/HikariCP

Aggiornamento n. 3: (settembre ’14) Si prega di considerare BoneCP deprecato a questo punto, raccomandando il passaggio a HikariCP .

Aggiornamento n. 4: (15 aprile) – Non possiedo più il dominio jolbox.com, ma il nuovo proprietario ha mantenuto il vecchio contenuto, quindi fai attenzione.

Ho avuto problemi con DBCP quando le connessioni sono scadute, quindi ho provato c3p0. Stavo per rilasciare questo alla produzione, ma poi ho iniziato il test delle prestazioni. Ho trovato che c3p0 si comportava terribilmente. Non ho potuto configurarlo per funzionare bene. L’ho trovato due volte più lento di DBCP.

Ho quindi provato il pool di connessioni Tomcat .

Questo era due volte più veloce di c3p0 e risolto altri problemi che stavo avendo con DBCP. Ho passato molto tempo a investigare e testare le 3 piscine. Il mio consiglio se si sta distribuendo su Tomcat è di utilizzare il nuovo pool JDBC di Tomcat.

Per il problema di riconnessione automatica con DBCP, è stato provato a utilizzare i seguenti 2 parametri di configurazione?

validationQuery="Some Query" testOnBorrow=true 

Utilizzano DBCP da un paio d’anni in produzione. È stabile, sopravvive al riavvio del server DB. Basta configurarlo correttamente. Richiede solo una manciata di parametri da specificare, quindi non essere pigro. Ecco uno snippet dal nostro codice di produzione del sistema che elenca i parametri che abbiamo impostato in modo esplicito per farlo funzionare:

 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"); 

Un’altra alternativa è HikariCP .

Ecco il punto di confronto

Ecco alcuni articoli che mostrano che DBCP ha prestazioni significativamente più elevate rispetto a C3P0 o Proxool. Inoltre, nella mia esperienza, c3p0 ha alcune caratteristiche interessanti, come il pool di statement preparato ed è più configurabile di DBCP, ma DBCP è chiaramente più veloce in qualsiasi ambiente in cui l’ho usato.

Differenza tra dbcp e c3p0? Assolutamente niente! (Un blog degli sviluppatori di Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Vedi anche l’articolo JavaTech “Connection Pool Showdown” nei commenti sul post del blog.

Un’altra alternativa, Proxool, è menzionata in questo articolo .

Potresti riuscire a scoprire perché Hibernate raggruppa c3p0 per l’implementazione del pool di connessioni di default?

Sfortunatamente sono tutti obsoleti. DBCP è stato aggiornato un po ‘di recente, gli altri due hanno 2-3 anni, con molti bug in sospeso.

Dbcp è pronto per la produzione se configurato correttamente.

Ad esempio, viene utilizzato su un sito Web commerciale di 350000 visitatori / giorno e con pool di 200 connessioni.

Gestisce molto bene i timeout a condizione che lo configuri correttamente.

La versione 2 è in corso e ha uno sfondo che lo rende affidabile poiché sono stati affrontati molti problemi di produzione.

Lo usiamo per la nostra soluzione batch server ed è in esecuzione centinaia di lotti che funzionano su milioni di righe nel database.

I test delle prestazioni eseguiti da tomcat jdbc pool mostrano che offre prestazioni migliori rispetto a cp30.

Ho appena finito di perdere un giorno e mezzo con DBCP. Anche se sto usando l’ultima versione di DBCP, mi sono imbattuto esattamente negli stessi problemi di j pimmel . Non consiglierei affatto a DBCP, specialmente se è imansible lanciare connessioni fuori dal pool quando il DB va via, la sua incapacità di riconnettersi quando il DB ritorna e la sua incapacità di aggiungere dynamicmente gli oggetti di connessione nel pool (si blocca per sempre leggere il socket JDBCconnect I / O)

Sto passando a C3P0 ora. L’ho usato nei progetti precedenti e ha funzionato ed eseguito come un incantesimo.

c3p0 è buono quando stiamo usando i progetti di mutithreading. Nei nostri progetti abbiamo utilizzato simultaneamente più esecuzioni di thread utilizzando DBCP, quindi abbiamo ottenuto il timeout della connessione se abbiamo utilizzato più esecuzioni di thread. Quindi siamo andati con la configurazione di c3p0.

Una buona alternativa che è facile da usare è DBPool .

“Un’utilità di pooling di connessioni database basata su Java, che supporta la scadenza basata sul tempo, il caching delle istruzioni, la convalida della connessione e la facile configurazione mediante un gestore di pool.”

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

Ci siamo imbattuti in una situazione in cui dovevamo introdurre il pool di connessioni e avevamo 4 opzioni di fronte a noi.

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

Abbiamo effettuato alcuni test e confronti in base ai nostri criteri e abbiamo deciso di optare per HikariCP. Leggi questo articolo che spiega perché abbiamo scelto HikariCP.

Per implementare il C3P0 nel modo migliore, controllare questa risposta

C3P0 :

Per l’applicazione aziendale, C3P0 è l’approccio migliore. C3P0 è una libreria di facile utilizzo per l’aumento di driver JDBC tradizionali (basati su DriverManager) con DataSource associabili JNDI, inclusi DataSource che implementano Connection and Statement Pooling, come descritto dalle specifiche jdbc3 e jdbc2 std. C3P0 ha inoltre gestito in modo robusto i disconnessioni DB e le riconnessioni trasparenti su CV, mentre DBCP non ha mai recuperato le connessioni se il collegamento è stato rimosso da sotto.

Ecco perché c3p0 e altri pool di connessione dispongono anche di cache di istruzioni preparate: consente al codice dell’applicazione di evitare di occuparsi di tutto ciò. Le dichiarazioni sono solitamente conservate in un pool LRU limitato, quindi le dichiarazioni comuni riutilizzano un’istanza PreparedStatement.

Peggio ancora DBCP stava restituendo gli oggetti Connection all’applicazione per la quale il trasporto sottostante si era rotto. Un caso di utilizzo comune per c3p0 è la sostituzione del pool di connessioni DBCP standard incluso in Apache Tomcat. Spesso, un programmatore si imbatte in una situazione in cui le connessioni non vengono correttamente riciclate nel pool di connessioni DBCP e in questo caso c3p0 è un valido sostituto.

Negli aggiornamenti correnti C3P0 ha alcune caratteristiche brillanti. quelli sono dati muggiti:

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

Qui, il limite massimo e minimo definisce i limiti di connessione, ovvero la connessione minima e massima che questa applicazione impiegherà. MaxIdleTime() definisce quando rilascerà la connessione intriggers.

DBCP :

Anche questo approccio è buono ma presenta alcuni inconvenienti come il timeout della connessione e la connessione in corso. C3P0 è buono quando stiamo usando i progetti di mutithreading. Nei nostri progetti abbiamo utilizzato simultaneamente più esecuzioni di thread utilizzando DBCP, quindi abbiamo ottenuto il timeout della connessione se abbiamo utilizzato più esecuzioni di thread. Quindi siamo andati con la configurazione di c3p0. Non consiglierei affatto a DBCP, specialmente se è imansible lanciare connessioni fuori dal pool quando il DB va via, la sua incapacità di riconnettersi quando il DB ritorna e la sua incapacità di aggiungere dynamicmente gli oggetti di connessione nel pool (si blocca per sempre leggere il socket JDBCconnect I / O)

Grazie 🙂