Pergunta

O que é a melhor maneira de gerenciar uma conexão de banco de dados em um servlet Java?

Atualmente, eu simplesmente abrir uma conexão na função init(), e depois fechá-lo em destroy().

No entanto, estou preocupado que "permanentemente" segurando em uma conexão de banco de dados pode ser uma coisa ruim.

Esta é a maneira correta de lidar com isso? Se não, quais são algumas opções melhores?

edit: para dar um pouco mais esclarecimentos:. Eu tentei simplesmente abrir / fechar uma nova conexão para cada solicitação, mas com testes que eu vi problemas de desempenho devido à criação de muitas conexões

Existe algum valor em compartilhar uma conexão através de vários pedidos? Os pedidos para esta aplicação são quase todos "read-only" e vêm muito rapidamente (embora os dados solicitados é relativamente pequeno).

Foi útil?

Solução

Na verdade, eu discordo com o uso Commons DBCP. Você realmente deve adiar para o recipiente para administrar o pool de conexão para você.

Uma vez que você estiver usando Java Servlets, que implica em execução em um contêiner Servlet, e todos os principais recipientes Servlet que eu estou familiarizado com a fornecer gerenciamento de pool de conexão (a especificação Java EE podem até mesmo exigir dele). Se o seu recipiente acontece de usar DBCP (como Tomcat faz), ótimo, caso contrário, é só usar o que o seu recipiente fornece.

Outras dicas

Como todo mundo diz, você precisa usar um pool de conexão. Por quê? E aí? Etc.

O que há de errado com a sua solução

Eu sei isso desde que eu também pensei que era uma boa ideia era uma vez. O problema é duas vezes:

  1. Todas as threads (pedidos servlet obter servido com um thread por cada) estarão compartilhando a mesma conexão. Os pedidos serão, portanto, são processadas uma de cada vez. Isto é muito lento, mesmo se você apenas sentar em um único navegador e inclinar-se sobre a tecla F5. Experimente:. Este material soa de alto nível e abstrato, mas é empírica e testável
  2. Se as quebras de conexão para qualquer razão, o método init não será chamado novamente (porque o servlet não será retirado de serviço). Não tente lidar com este problema, colocando um try-catch no doGet ou doPost, porque então você vai estar no inferno (espécie de escrever um servidor de aplicativo sem ser solicitado).
  3. Ao contrário do que se poderia pensar, você não terá problemas com transações, desde o início transação fica associado com o segmento e não apenas a conexão. Eu posso estar errado, mas desde que esta é uma solução ruim de qualquer maneira, não se preocupe.

Por Connection Piscina

pools de conexão dar-lhe um monte de vantagens, mas acima de tudo eles resolvem os problemas de

  1. Fazer uma conexão de banco de dados real é caro. O pool de conexão sempre tem algumas conexões extras ao redor e dá-lhe um desses.
  2. Se as conexões falharem, o pool de conexão sabe como abrir um novo
  3. Muito importante: cada segmento tem sua própria conexão. Isto significa que rosqueamento é tratado onde deve estar: no nível de DB. DBs são super eficiente e pode lidar com solicitação simultânea com facilidade.
  4. Outras coisas (como a centralização localização do JDBC seqüências de conexão, etc.), mas há milhões de artigos, livros, etc. nesta

Quando para obter uma conexão

Em algum lugar na pilha de chamadas iniciado em seu delegado serviço (doPost, doGet, doDisco, seja qual for), você deve ter uma conexão e, em seguida, você deve fazer a coisa certa e devolvê-lo em um bloco finally. I deve mencionar que o C # arquiteto principal cara disse uma vez um tempo em que você deve usar blocos finally 100x mais de blocos catch. palavras mais verdadeiras nunca falado ...

Que Connection Piscina

Você está em um servlet, então você deve usar o pool de conexão do recipiente fornece. Seu código JNDI será completamente normal, exceto pela forma como você obter a conexão. Tanto quanto eu sei, todos os contêineres de servlet tem pools de conexão.

Alguns dos comentários sobre as respostas acima sugerem usando um determinado pool de conexão API em seu lugar. Seu WAR deve ser portátil e "apenas implantar." Eu acho que isso é basicamente errado. Se você usar o pool de conexão fornecido pelo seu recipiente, a sua aplicação será implementável em recipientes que se estendem por várias máquinas e todo esse material de fantasia que a especificação Java EE fornece. Sim, os descritores de implementação específicos do recipiente terá que ser escrito, mas essa é a maneira EE, seg.

Um comentarista menciona que certos pools de conexão fornecido por contêiner não funcionam com drivers JDBC (ele / ela menciona Websphere). Isso soa totalmente inverosímil e ridículo, por isso é provavelmente verdade. Quando coisas assim acontece, lance tudo que você está "deve fazer" no lixo e fazer o que puder. Isso é o que somos pagos para, às vezes:)

Eu usaria Commons DBCP . É um projeto Apache que gerencia o pool de conexão para você.

Você tinha acabado de obter a sua conexão em seu doGet ou doPost executar a consulta e, em seguida, fechar a conexão em um bloco finally. (Con.close () simplesmente retorna para a piscina, que na verdade não fechá-lo).

DBCP pode gerenciar o tempo limite de conexão e recuperar a partir deles. A maneira que você está fazendo as coisas se o seu banco de dados vai para baixo para qualquer período de tempo que você terá que reiniciar o aplicativo.

Você está reunindo suas conexões? Se não, você provavelmente deve reduzir a sobrecarga de abrir e fechar suas conexões.

Uma vez que está fora do caminho, basta manter a conexão aberta por tanto tempo quanto a sua necessidade, como John sugeriu.

A melhor maneira, e eu estou navegando através do Google para uma folha de referência melhor, é usar piscinas.

Na inicialização, você cria um pool que contém um número X de objetos de conexão SQL para seu banco de dados. Armazenar esses objetos em algum tipo de lista, como ArrayList. Cada um destes objectos tem um boolean privado para 'isLeased', um longo para o tempo que foi utilizado pela última vez e uma conexão. Sempre que você precisar de uma conexão, você solicitar um da piscina. A piscina será ou dar-lhe a primeira conexão disponível, verificando a variável isLeased, ou ele vai criar um novo e adicioná-lo à piscina. Certifique-se de definir o timestamp. Uma vez que você é feito com a conexão, simplesmente devolvê-lo para a piscina, que irá definir isLeased como falsa.

Para não constantemente ter conexões amarrar o banco de dados, você pode criar um segmento de trabalho que irá ocasionalmente atravessar a piscina e ver quando a última vez que uma conexão foi usado. Se ele tem sido longo o suficiente, ele pode fechar essa conexão e removê-lo da piscina.

Os benefícios da utilização deste, é que você não tem o tempo de espera longa espera para um objeto de conexão para se conectar ao banco de dados. Suas conexões já estabelecidas podem ser reutilizados tanto quanto você gosta. E você vai ser capaz de definir o número de conexões com base em quão ocupado você acha que a sua aplicação será.

Você só deve manter uma conexão com o banco aberto durante o tempo que você precisar dele, que depende do que você está fazendo é, provavelmente, no âmbito dos seus métodos doGet/doPost.

Piscina-lo.

Além disso, se você está fazendo matéria-JDBC, você pode olhar para algo que ajuda a gerenciar a conexão, PreparedStatement, etc. A menos que você tem muito apertados requisitos "leveza", usando o suporte JDBC do Spring, por exemplo, vai simplificar seu código muito- e você não é obrigado a usar qualquer outra parte da Primavera.

Veja alguns exemplos aqui:

http://static.springframework.org/spring /docs/2.5.x/reference/jdbc.html

pool de conexão

A associada a uma fonte de dados deve fazer o truque. Você pode se apossar da conexão da fonte de dados no método de solicitação de servlet (doget / dopost, etc).

DBCP, c3p0 e muitas outras pools de conexão pode fazer o que você está procurando. Enquanto você está pool de conexões, você pode querer Demonstrações piscina e PreparedStatements; Além disso, se você é um ambiente LEIA HEAVY como você indicou, você pode querer armazenar em cache alguns dos resultados usando algo como ehcache.

BR,
~ A

Normalmente, você vai descobrir que as conexões de abertura por solicitação é mais fácil de gerir. Isso significa que no doPost () ou o método doGet () do servlet.

Se o abrir com o init () torna disponível a todos os pedidos e o que acontece quando você tem solicitações simultâneas?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top