Pool DBCP[RESOLVIDO]  XML
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Autor Mensagem
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Bom dia a todos

Estava eu em um tópico na semana passada falando sobre conexões JDBC quando o vinny disse que uma boa prática para a aplicações desktop era fornecer conexões por meio de uma api especializada, e para isso e por isso me indicou o DBCP da apache.

Bom, eu fui no google pesquisei um bocado e encontrei um exemplo que me mostra como criar um pool, mas ainda não estou enxergando a vantagem disso. Estou dizendo isso por que eu não consegui por exemplo configurar a quantidade de conexões que o pool deve fornecer (nesse caso apenas uma) e por isso eu gostaria da opinião dos colegas a respeito da classe que foi criada.
O exemplo que estudei não foi copiado na integra coloquei algumas coisas minhas no meio mas em suma a classe está funcionando mas eu ainda não sei se essa é a forma ideal.
Segue a classe:



Gostaria de saber se essa classe fornece meios de se controlar o pool de conexões para que sempre fique ao menos uma conexão aberta

PS: Isso será usado em aplicações desktop/Swing

Agradeço a atenção de todos

This message was edited 2 times. Last update was at 24/09/2010 14:01:47


Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

Você deveria limitar suas conexões a "pelo menos uma", não a "exatamente uma".

A vantagem é que múltiplas threads podem se beneficiar de parelismo no banco, quando usam conexões diferentes.

Outra vantagem é configurar o DBCP para testar a qualidade da conexão antes de retorna-la. Assim, ele mesmo se encarrega de reabrir a conexão caso ela caia, o que pode ocorrer caso o servidor detecte que ela está inativa por muito tempo.

@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

No caso do código acima aonde eu poderia então configurar o pool para criar ao menos uma conexão (na verdade foi falha de comunicação pois minha intenção era justamente essa, de deixar sempre pelo menos uma conexão aberta, ativa e operante).
Da forma como está eu não consigo "devolver" a conexão utilizada ou iniciar o pool com uma conexão já criada.

Agradeço a atenção.

Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

No lugar do PoolingDataSource, use o BasicDataSource:
http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html

Ele tem diversas configurações.

@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Eu já tinha criado esse objeto em outra classe aqui, mas me faltou um pouco mais de curiosidade para ver que com o método setInitialSize(int initialSize) para criar um número padrão de conexões, mas ainda não entendi como faço para devolver a conexão que já foi usado ou então como fecha-lá mantendo a conexão padrão que deve estar ativa.
Eu implementei o exemplo do BasicDataSource e lendo ele com calma não encontrei o lugar onde ele devolve a conexão ao pool, nesse caso ele apenas fecha a conexão e deu.

This message was edited 1 time. Last update was at 23/09/2010 11:50:40


Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

Na verdade, basta fechar a conexão que o pool retornou.

A conexão retornada pelo pool é um wrapper. Os métodos para criar statements são delegados para a sua conexão real. O método close(), ao invés de fechar a conexão real, a devolve para o pool.

Dessa forma vc usa o pool de forma transparente, sem precisar reescrever o código todo.

This message was edited 1 time. Last update was at 23/09/2010 11:52:29


@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Nesse caso ao dar um:



A conexão real não é fechada e sim a conexão que o getConnection retornou? Apesar de ela ser do pacote java.sql.Connection?

This message was edited 1 time. Last update was at 23/09/2010 12:06:15


Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

laudenpower wrote:A conexão real não é fechada e sim a conexão que o getConnection retornou? Apesar de ela ser do pacote java.sql.Connection?


Sim. java.sql.Connection é só uma interface.
A classe concreta deve ser algo como PooledConnection, que controla a sua java.mysql.Connection.

(os nomes podem não ser exatamente esse, mas vc entendeu a idéia.)

@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Nesse caso tem algo faltando...
O BasicDataSource por ele mesmo não possui nenhum método que me retorne implementação de Connection diferente. Li a documentação (pode ser até que deixei algo passar) e lá a única coisa que me retorna uma conexão é o getConnection() da classe BasicDataSource e nesse caso o Retorno é um objeto do tipo Connection "normal" vamos dizer assim.
A minha intenção é deixar ao menos uma conexão disponível o tempo todo na aplicação, caso ela já esteja sendo usada o pool deve criar uma nova (em ambientes concorridos por exemplo), caso contrário ele deve retornar a conexão que já está aberta.
Acontece que cada vez que crio um dao eu chamo no contrutor o getConnection() do BasicDataSource e nessa brincadeira ele cria uma nova conexão sendo que se ao final eu der um close nessa conexão ele não a reutiliza mais necessitando dar um novo getConnection().
Espero ter sido mais claro dessa vez

Se eu estiver confuso e não estiver vendo algo obvio peço desculpas e paciencia

Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

O close() dele não fecha a conexão. Só retorna para o BasicDataSource.

Tente imprimir o tipo de conexão com:


E veja o nome que ele retorna.

This message was edited 1 time. Last update was at 23/09/2010 14:44:23


@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Nessa parte você tem razão, pois ele retorna o nome da classe PoolGuardConnectionWrapper, porém por que ao fechar essa conexão com o método close() se eu tentar utilizar o dao novamente por que dá uma exeção de Connection closed??
Acredito que se fosse da forma como você explicou o close não fecharia de fato apenas devolveria a conexão para o dataSource né?
Tem mais um detalhe, cada dao que crio e chamo o getConnection() ele gera uma nova conexão, e posso ver isso pelo método dataSource.getNumActive() pois ele incrementa medida que vou criando conexões.
Tipo eu gostaria que compartilhar a mesma conexão entre todos e só criar uma nova se e somente se a primeira conexão estiver "ocupada" por outro processo.

Valeu mesmo pela ajuda viu?

This message was edited 1 time. Last update was at 23/09/2010 15:02:50


Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

Você não pode tentar reusar a mesma conexão, precisar refazer o getConnection do pool. A diferença é que ele não vai criar uma nova, mas sim, retornar a que acabou de voltar pro pool. Tudo isso de forma transparente.


PS: Eu usava o Spring pra controlar o pool de conexões para mim. Ele se encarrega de solicitar para o pool, fechar statements, resultsets e connections. Sem falar que ele tem alguns métodos para inserts e deletes em massa, que economizam muita performance.

@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Pera, então o getConnection() não cria um conexão "nova" (novinha mesmo, que fica contabilizada lá no banco)?
Tipo nesse caso ele dá a impressão de criar uma nova? Pergunto isso por que pra mim conexão nova em JDBC puro é aquela que a gente cria usando o DriverManager.getConnection("url","usuario","senha"), nesse caso o getConnection() faz isso apenas uma vez (no caso de eu ter configurado o pool para apenas uma conexão) e depois não faz mais, apenas pegando o que já foi criado?
Se for isso então as conexões ativas que o dataSource.getNumActive() mostra não é o número de conexões criadas e sim o número de classes que estão fazendo uso dessa conexão?
Acho que tô "quase" lá, se explicares isso acho que desamarro o nó da minha cabeça.

Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

Esse getConnection() faz o seguinte:

Existe uma conexão livre, criada e aberta?
- Se sim, retorna a conexão livre

Se não. O número de conexões existentes, está abaixo do limite?
- Se sim, cria a conexão, abre e retorna.
- Se não, dá uma SQLException



A conexão só é realmente fechada com um close() real quando estourar o tempo de ociosidade que você configurar no pool.

This message was edited 1 time. Last update was at 23/09/2010 15:59:16


@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Então se eu configurei o pool para deixar pelo menos uma conexão aberta e essa conexão estourou o tempo de ociosidade a mesma é fechada de "verdade" pelo pool, enquanto isso ele mantém ela aberta?
E mais uma duvida, se eu tenho uma conexão sendo usada, o pool vai lá e cria uma nova para outro processo nesse momento eu vou ter duas conexões simultâneas com o banco de dados ao terminar as operações o que acontece com a segunda? Ela é fechada e permanece apenas uma aberta (de acordo com a minha configuração)?
Tava precisando de uma forma de testar isso olhando no banco como a coisa está se comportando (tipo quantas conexões estão abertas entre outras coisas)...

Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
 
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Ir para:   
Powered by JForum 2.1.8 © JForum Team