Opções de conjunto de conexões com JDBC: DBCP vs C3P0

312

Qual é a melhor biblioteca de conjunto de conexões disponível para Java / JDBC?

Estou considerando os 2 principais candidatos (de código aberto / gratuito):

Eu li muito sobre eles em blogs e outros fóruns, mas não consegui tomar uma decisão.

Existem alternativas relevantes para esses dois?

Dema
fonte

Respostas:

181

O DBCP está desatualizado e não possui grau de produção. Algum tempo atrás, realizamos uma análise interna dos dois, criando um equipamento de teste que gerava carga e concorrência contra os dois para avaliar sua adequação sob condições reais da vida.

O DBCP gerou exceções de maneira consistente em nosso aplicativo de teste e lutou para alcançar níveis de desempenho que o C3P0 era mais do que capaz de manipular sem nenhuma exceção.

O C3P0 também tratou com segurança as desconexões de DB e as reconexões transparentes no currículo, enquanto o DBCP nunca recuperou conexões se o link foi retirado por baixo. Pior ainda, o DBCP estava retornando objetos de Conexão para o aplicativo para o qual o transporte subjacente havia sido interrompido.

Desde então, usamos o C3P0 em quatro principais aplicativos da Web para consumidores pesados, e nunca olhamos para trás.

ATUALIZAÇÃO: Acontece que, após muitos anos sentados em uma prateleira, o pessoal do Apache Commons tirou o DBCP da dormência e agora é, mais uma vez, um projeto desenvolvido ativamente. Assim, minha postagem original pode estar desatualizada.

Dito isto, ainda não experimentei o desempenho desta nova biblioteca atualizada, nem ouvi falar de fato em nenhuma estrutura de aplicativo recente.

j pimmel
fonte
2
Obrigado! E a alternativa Proxool sugerida? A versão atual do Hibernate vem com o c3p0 e o Proxool.
Dema
Nós não tentamos Proxool mas eu vou certifique-se de verificá-la agora :)
j pimmel
5
c3p0 tem algumas desvantagens. às vezes falha ao lidar com picos de conexão.
Janning
3
as coisas mudaram muito desde os 4 anos em que você postou esta resposta, você pode adicionar uma atualização que compartilhe o cenário atual, se possível?
Rajat Gupta
13
Eu recomendo o HikariCP , mas depois ajudei a escrevê-lo.
brettw
177

Convido você a experimentar o BoneCP - é gratuito, de código aberto e mais rápido que as alternativas disponíveis (consulte a seção de benchmark).

Disclaimer: Eu sou o autor, então você pode dizer que sou tendencioso :-)

ATUALIZAÇÃO: em março de 2010, ainda era cerca de 35% mais rápido que o novo pool reescrito do Apache DBCP ("tomcat jdbc"). Consulte o link de benchmark dinâmico na seção benchmark.

Atualização # 2: (dez '13) Após 4 anos no topo, agora existe um concorrente muito mais rápido: https://github.com/brettwooldridge/HikariCP

Atualização # 3: (Set '14) Por favor, considere que o BoneCP está obsoleto neste momento, recomendamos a mudança para o HikariCP .

Atualização # 4: (abril '15) - Não sou mais o proprietário do domínio jolbox.com

wwadge
fonte
1
Realmente adoraria obter uma solução de problemas usando o BoneCP como uma fonte de dados do Tomcat. O principal problema que tive com isso foi que ele exigia as Classes BoneCP no diretório dir do tomcat, bem como as classes log4j e google. Isso fez com que os pools de conexão funcionassem - (não funcionou no WAR) - no entanto, conflitava com a configuração log4j do Tomcat e impedia qualquer saída de log do aplicativo, que era um desagradável ...
j pimmel
1
Isso soa como um problema do log4j mais do que qualquer outra coisa. Deixe-me uma linha no forum.jolbox.com e eu vou ajudá-lo a encontrá-lo o mais rápido possível.
wwadge
3
1up, BoneCP é brilhante. Comutado de C3P0. Ele até me permitiu remover minha dependência do log4jdbc-remix, porque permite o logout de instruções fora da caixa!
Sub-
68
+1 para atualizar sobre algo que você não escreveu sendo mais rápido!
precisa saber é o seguinte
1
@AndrewScottEvans Provavelmente melhor para reverter para v0.7.1
wwadge
16

Eu estava tendo problemas com o DBCP quando o tempo limite das conexões expirou, então testei o c3p0. Ia lançar isso para produção, mas depois comecei a testar o desempenho. Eu descobri que o c3p0 teve um desempenho terrível. Não consegui configurá-lo para ter um bom desempenho. Eu achei duas vezes mais lento que o DBCP.

Eu tentei o pool de conexões do Tomcat .

Isso foi duas vezes mais rápido que o c3p0 e corrigiu outros problemas que eu estava tendo com o DBCP. Passei muito tempo investigando e testando as 3 piscinas. Meu conselho se você estiver implantando no Tomcat é usar o novo pool JDBC do Tomcat.

user542651
fonte
14

Para o problema de reconexão automática com DBCP, alguma vez tentou usar os 2 parâmetros de configuração a seguir?

validationQuery="Some Query"

testOnBorrow=true
Brandon Teo
fonte
Quanto à documentação , testOnBorrowpossui valor padrão true, portanto, se validationQueryfor definido, o DBCP testará todas as conexões antes de serem passadas para o aplicativo.
dma_k
12

Usam o DBCP há alguns anos na produção. É estável, sobrevive à reinicialização do servidor DB. Basta configurá-lo corretamente. Requer apenas alguns parâmetros a serem especificados, portanto, não seja preguiçoso. Aqui está um trecho do código de produção do sistema que lista os parâmetros que definimos explicitamente para fazê-lo funcionar:

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ᴉɹǝɥɔ
fonte
8

Aqui estão alguns artigos que mostram que o DBCP tem desempenho significativamente superior ao C3P0 ou Proxool. Também na minha própria experiência, o c3p0 possui alguns recursos interessantes, como o pool de instruções preparado e é mais configurável que o DBCP, mas o DBCP é claramente mais rápido em qualquer ambiente em que o usei.

Diferença entre dbcp e c3p0? Absolutamente nada! (Um blog para desenvolvedores do Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Veja também o artigo da JavaTech "Connection Pool Showdown" nos comentários da postagem do blog.

Divyesh Kanzariya
fonte
4
mais rápido em ambientes de thread único, talvez, com bugs e instável e simplesmente quebrado em qualquer outro lugar.
7

Outra alternativa, o Proxool, é mencionada neste artigo .

Você pode descobrir por que o Hibernate empacota o c3p0 para a implementação padrão do conjunto de conexões?

kit de ferramentas
fonte
7

Infelizmente, todos estão desatualizados. O DBCP foi atualizado um pouco recentemente, os outros dois têm de 2 a 3 anos, com muitos erros pendentes.


fonte
Isso é verdade - a última versão do C3PO (versão 0.9) é de maio de 2007. A versão mais recente do Proxool (versão 0.9) é de agosto de 2008. A última versão do DBCP também é de abril de 2007, mas pelo menos é uma versão 1.2 estável. Existe algo realmente mantido por aí?
Guss
4
Para ser justo, esses não são grandes projetos; portanto, você deve esperar cada vez menos atualizações no C3P0 / DBCP e o tempo passa.
Wwadge
7

Dbcp está pronto para produção, se configurado corretamente.

É usado, por exemplo, em um site comercial de 350000 visitantes / dia e com pools de 200 conexões.

Ele lida com tempos limite muito bons, desde que você o configure corretamente.

A versão 2 está em andamento e possui um histórico que a torna confiável, pois muitos problemas de produção foram resolvidos.

Nós o usamos para nossa solução de servidor em lote e ele está executando centenas de lotes que funcionam em milhões de linhas no banco de dados.

Os testes de desempenho executados pelo pool tomcat jdbc mostram que ele tem melhor desempenho que o cp30.

PACOTE DE CARGA UBIK
fonte
UBIK LOAD PACK - Estamos usando o DBCP 1.4 e enfrentando constantes interrupções do nosso único lote com 10000 registros. Estamos usando o Spring Batch + JSR 352 e pensando em mudar para o HikariCP. Quando você diz, centenas de lotes rodando sem problemas, você quer dizer que está rodando com o DBCP 2.x ou qualquer outra versão? Além disso, você se importaria de compartilhar as configurações? Nossa configuração é maxActive = 150, minIdle = 15, maxIdle = 75, initialSize = 15, mas ainda não vi interrupções desaparecerem. Não estamos usando nenhuma validationQuery ou testOnBorrow / testOnReturn. Você recomenda usá-lo?
Yogendra
4

Acabei de perder um dia e meio com o DBCP. Embora eu esteja usando a versão mais recente do DBCP, tive exatamente os mesmos problemas que o j pimmel . Eu não recomendaria o DBCP, especialmente a habilidade de lançar conexões para fora do pool quando o DB desaparecer, sua incapacidade de se reconectar quando o DB voltar e sua incapacidade de adicionar dinamicamente objetos de conexão de volta ao pool (ele fica suspenso para sempre uma leitura do soquete de E / S JDBCconnect pós)

Estou mudando para o C3P0 agora. Eu usei isso em projetos anteriores e funcionou e se apresentou como um encanto.

Larry H
fonte
4

c3p0 é bom quando estamos usando projetos de leitura múltipla. Em nossos projetos, usamos simultaneamente várias execuções de encadeamentos usando DBCP, e obtemos o tempo limite da conexão se usamos mais execuções de encadeamentos. Então fomos com a configuração c3p0.

nns
fonte
3

Uma boa alternativa fácil de usar é o DBPool .

"Um utilitário de pool de conexão de banco de dados baseado em Java, que suporta expiração com base no tempo, cache de instruções, validação de conexão e configuração fácil usando um gerenciador de pool".

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

Soundlink
fonte
Comparei DBPool vs BoneCP. O DBPool torna o getConnection () sincronizado entre outras coisas e é muito mais lento que o BoneCP (consulte: jolbox.com/forum/viewtopic.php?f=3&t=175 ).
wwadge
3

Nos deparamos com uma situação em que precisávamos introduzir o pool de conexões e tínhamos quatro opções à nossa frente.

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

Realizamos alguns testes e comparações com base em nossos critérios e decidimos optar pelo HikariCP. Leia este artigo que explica por que escolhemos o HikariCP.

Jeevan Patil
fonte
1

Para implementar o C3P0 da melhor maneira, verifique esta resposta

C3P0 :

Para aplicativos corporativos, o C3P0 é a melhor abordagem. O C3P0 é uma biblioteca fácil de usar para aumentar os drivers JDBC tradicionais (baseados no DriverManager) com DataSources vinculáveis ​​a JNDI, incluindo DataSources que implementam o Connection and Statement Pooling, conforme descrito nas extensões jdbc3 spec e jdbc2 std. O C3P0 também tratou com segurança as desconexões de DB e as reconexões transparentes no currículo, enquanto o DBCP nunca recuperou conexões se o link foi retirado por baixo.

Portanto, é por isso que o c3p0 e outros conjuntos de conexões também prepararam caches de instruções - ele permite que o código do aplicativo evite lidar com tudo isso. As instruções geralmente são mantidas em algum pool limitado de LRU; portanto, instruções comuns reutilizam uma instância de PreparedStatement.

Pior ainda, o DBCP estava retornando objetos de Conexão para o aplicativo para o qual o transporte subjacente havia sido interrompido. Um caso de uso comum para c3p0 é substituir o conjunto de conexões DBCP padrão incluído no Apache Tomcat. Muitas vezes, um programador enfrenta uma situação em que as conexões não são recicladas corretamente no conjunto de conexões DBCP e o c3p0 é um substituto valioso nesse caso.

Nas atualizações atuais, o C3P0 possui alguns recursos brilhantes. estes são dados abaixo:

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

Aqui, máximo e mínimo poolsize definir limites de conexão que meios como mínima e máxima de conexão esta aplicação irá tomar. MaxIdleTime()defina quando liberará a conexão inativa.

DBCP :

Essa abordagem também é boa, mas tem algumas desvantagens, como o tempo limite da conexão e a liberação da conexão. C3P0 é bom quando estamos usando projetos de leitura mútua. Em nossos projetos, usamos simultaneamente várias execuções de encadeamentos usando DBCP, e obtemos o tempo limite da conexão se usamos mais execuções de encadeamentos. Então fomos com a configuração c3p0. Eu não recomendaria o DBCP, especialmente a habilidade de lançar conexões para fora do pool quando o DB desaparecer, sua incapacidade de se reconectar quando o DB voltar e sua incapacidade de adicionar dinamicamente objetos de conexão de volta ao pool (ele fica suspenso para sempre uma leitura do soquete de E / S JDBCconnect pós)

Obrigado :)

Md. Sajedul Karim
fonte
1

minha recomendação é

hikari> druid> UCP> c3p0> DBCP

É baseado no que eu testei - 20190202, no meu ambiente de teste local (4GB mac / mysql no docker / pool minSize = 1, maxSize = 8), o hikari pode servir 1024 threads x 1024 vezes para obter conexões, tempo médio para cada thread o final é de 1 ou 2 milhões de segundos, enquanto o c3p0 pode servir apenas 256 threads x 1024 vezes e o tempo médio para cada thread já é de 21 milhões de segundos. (512 threads falharam).

Kyle Zhang
fonte