Opções de pool de conexão com JDBC: DBCP vs C3P0

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

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

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

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

Existem alternativas relevantes para esses dois?

O DBCP está desatualizado e não está no nível de produção. Algum tempo atrás nós conduzimos uma análise interna dos dois, criando um dispositivo de teste que gerou carga e simultaneidade contra os dois para avaliar sua adequação sob condições da vida real.

O DBCP consistentemente gerou exceções 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 exceções.

O C3P0 também tratou de forma robusta as desconexões de database e as reconexões transparentes na reboot, enquanto o DBCP nunca recuperou as conexões se o link foi retirado por baixo dele. Pior ainda, o DBCP estava retornando os objects Connection para o aplicativo para o qual o transporte subjacente havia quebrado.

Desde então, usamos o C3P0 em 4 grandes aplicativos web de carga pesada e nunca olhamos para trás.

ATUALIZAÇÃO: Acontece que depois de muitos anos sentado em uma prateleira, o pessoal do Apache Commons tirou o DBCP da dormência e agora é, mais uma vez, um projeto desenvolvido ativamente. Assim, meu post original pode estar desatualizado.

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

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

Disclaimer: Eu sou o autor, então você poderia dizer que sou preconceituoso 🙂

ATUALIZAÇÃO: A partir de março de 2010, ainda é cerca de 35% mais rápido do que o novo pool reescrito do Apache DBCP (“tomcat jdbc”). Veja o link de benchmark dynamic na seção de benchmark.

Atualização # 2: (Dez ’13) Depois de 4 anos no topo, agora há um concorrente muito mais rápido: https://github.com/brettwooldridge/HikariCP

Atualização # 3: (Set ’14) Por favor, considere o BoneCP obsoleto neste ponto, recomende mudar para o HikariCP .

Atualização # 4: (15 de abril) – Eu não possuo mais o domínio jolbox.com, mas o novo proprietário manteve o conteúdo antigo, então tenha cuidado.

Eu estava tendo problemas com o DBCP quando as conexões esgotaram, então testei o c3p0. Eu ia liberar isso para a produção, mas depois comecei a testar o desempenho. Eu achei que c3p0 realizado terrivelmente. Eu não consegui configurá-lo para um bom desempenho. Eu achei duas vezes mais lento que o DBCP.

Eu então tentei o pool de conexão 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 os 3 pools. Meu conselho, se você estiver implantando no Tomcat, é usar o novo pool JDBC do Tomcat.

Para o problema de reconexão automática com o DBCP, alguma tentativa foi feita usando os dois parâmetros de configuração a seguir?

validationQuery="Some Query" testOnBorrow=true 

Utiliza o DBCP há alguns anos em produção. É estável, sobrevive à reboot do servidor de database. Basta configurá-lo corretamente. Isso requer apenas alguns parâmetros a serem especificados, portanto, não seja preguiçoso. Aqui está um trecho do nosso código de produção do sistema, que lista os parâmetros que definimos explicitamente 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"); 

Outra alternativa é o HikariCP .

Aqui está o benchmark de comparação

Aqui estão alguns artigos que mostram que o DBCP tem um desempenho significativamente maior que o C3P0 ou o Proxool. Também na minha própria experiência, o c3p0 tem alguns resources interessantes, como o agrupamento 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 de desenvolvedores do Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Veja também o like no artigo JavaTech “Connection Pool Showdown” nos comentários na postagem do blog.

Outra alternativa, Proxool, é mencionada neste artigo .

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

Infelizmente eles estão todos desatualizados. DBCP foi atualizado um pouco recentemente, os outros dois são de 2-3 anos, com muitos bugs pendentes.

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

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

Ele manipula muito bem os tempos limite, desde que você o configure corretamente.

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

Usamos isso para a nossa solução de servidor em lotes e ele está executando centenas de lotes que funcionam em milhões de linhas no database.

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

Acabei de perder um dia e meio com o DBCP. Embora eu esteja usando a última versão do DBCP, eu tive exatamente os mesmos problemas que o j pimmel fez. Eu não recomendaria o DBCP, especialmente o jeito de lançar conexões fora do pool quando o database desaparece, sua incapacidade de se reconectar quando o database volta e sua incapacidade de adicionar dinamicamente objects de conexão de volta ao pool um post de soquete de E / S do JDBCconnect lido)

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

c3p0 é bom quando estamos usando projetos mutithreading. Em nossos projetos, usamos simultaneamente múltiplas execuções de thread usando o DBCP, então temos o tempo limite de conexão se usarmos mais execuções de thread. Então nós fomos com a configuração c3p0.

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

“Um utilitário de pool de conexão de database baseado em Java, suportando expiração baseada em tempo, cache de instruções, validação de conexão e configuração fácil usando um gerenciador de conjunto.”

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

Nós nos deparamos com uma situação em que precisávamos introduzir o pool de conexão e tínhamos 4 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 porque escolhemos o HikariCP.

Para implementar o C3P0 da melhor maneira, verifique esta resposta

C3P0 :

Para aplicativos corporativos, o C3P0 é a melhor abordagem. C3P0 é uma biblioteca fácil de usar para aumentar os drivers JDBC tradicionais (baseados em DriverManager) com DataSources vinculáveis ​​a JNDI, incluindo DataSources que implementam Connection e Statement Pooling, conforme descrito pelas especificações jdbc3 e pela extensão jdbc2 std. O C3P0 também tratou de forma robusta as desconexões de database e as reconexões transparentes na reboot, enquanto o DBCP nunca recuperou as conexões se o link foi retirado por baixo dele.

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

Pior ainda, o DBCP estava retornando os objects Connection para o aplicativo para o qual o transporte subjacente havia quebrado. Um caso de uso comum para c3p0 é replace o pool de conexão DBCP padrão incluído com o Apache Tomcat. Muitas vezes, um programador irá encontrar uma situação em que as conexões não são corretamente recicladas no conjunto de conexões DBCP e c3p0 é um substituto valioso neste caso.

Nas atualizações atuais, o C3P0 tem alguns resources shinys. aqueles são dados abaixo:

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

Aqui, poolsize máximo e mínimo definem os limites da conexão, o que significa como a conexão mínima e máxima será executada por esse aplicativo. MaxIdleTime() define quando liberará a conexão inativa.

DBCP :

Essa abordagem também é boa, mas tem algumas desvantagens, como tempo limite de conexão e realeasing de conexão. O C3P0 é bom quando estamos usando projetos mutitivos. Em nossos projetos, usamos simultaneamente múltiplas execuções de thread usando o DBCP, então temos o tempo limite de conexão se usarmos mais execuções de thread. Então nós fomos com a configuração c3p0. Eu não recomendaria o DBCP, especialmente o jeito de lançar conexões fora do pool quando o database desaparece, sua incapacidade de se reconectar quando o database volta e sua incapacidade de adicionar dinamicamente objects de conexão de volta ao pool um post de soquete de E / S do JDBCconnect lido)

Obrigado 🙂