| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 05/01/2012 07:35:34
|
ViniGodoy
Moderador
![[Avatar]](/images/avatar/1921493b5362e63fbe8983f4bd54157d.png)
Membro desde: 11/12/2006 08:22:01
Mensagens: 20587
Localização: Curitiba/PR
Offline
|
Calma gente, também não é para tanto.
Aqui na Positivo usamos o SQL em uma situação muito parecida com a sua: boa parte da lógica de negócio está em SPs, no banco.
Atualmente essa é uma prática desatualizada, principalmente no caso dos sistemas webs. Os bancos de dados tem um problema sério, que é ter pouca escalabilidade horizontal. Por isso, a tendência é mover a lógica para os servidores de aplicação, mesmo que eles tenham uma performance menor à princípio. É barato e fácil adicionar um servidor à infra-estrutura.
No caso de sistemas Desktop, eu ainda prefiro usar o Pool, mas se você tomar cuidado, não creio que nada de castastrófico irá ocorrer. Você pode facilmente verificar se a conexão está viva antes de retorna-la. Só cuidado com gargalos na parte de multi-threading, o que não é um problema no seu SGDB específico (o Oracle gerencia isso pelos Statements, não pelas conexõ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 |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 05/01/2012 07:56:56
|
maior_abandonado
JWizard
![[Avatar]](/images/avatar/0d7c463832b871c20405a6c9296b5517.jpg)
Membro desde: 03/09/2007 11:30:08
Mensagens: 2694
Localização: sp
Offline
|
Tchello wrote:
mauricioadl wrote:O problema continua prq vc abre a conexao em todos os selects;
seu codigo precisa de algumas correções.
1º use um fabrica de conexoes, procure aqui no forum que deve ter um monte de coisa a respeito
2º faça com que sua conexão seja um singleton e a mantenha aberta durante o uso da aplicacao, eh menos custoso do que abrir e fechar
3º nunca use statement troque por preparedStatement eh melhor e mais seguro
O uso de singletons deve ser feito somente com supervisão de um adulto. Evite-os a todo custo, a grande maioria esmagadora da utilização de Singletons é desnecessária tanto que esse se tornou um anti-padrão documentado (embora esteja como um padrão de projetos no livro do GoF).
Não mantenha uma conexão aberta durante a vida toda da aplicação, no final das contas essa será encerrada pelo próprio SGBD e você morrerá com uma exception ao tentar usa-la.
Isso sem contar que estará guardando um recurso desnecessariamente, aumento o custo computacional da aplicação.
O correto é abrir uma conexão por transação necessária e encerra-la tão logo a transação finalize.
Seria de bom tom (e mais inteligente) o uso de um pool de conexões, deixando que esse gerencie as conexões, cabendo a você pedi-las e devolve-las no inicio e fim das transações respectivamente, ficando transparente a quem a usa detalhes como usuário e senha do banco (algo semelhante a factory de conexões).
Existem dezenas de pools por ai, de uma olhada no C3PO e Nano Pool, embora existam outras alternativas.
Neste caso eu discordo por causa de uma questão de contexto:
mateusviccari wrote:Olá, estou fazendo um programa que usa conexão com o Postgres, fiz um cadastro de clientes e pra teste inclui 10.000 egistros pra ver como se comportava.
Fiz uma janelinha tambem pra mostrar as informações dos clientes, aonde tenho uma tabela que mostra todos os clientes cadastrados, e na tabela fiz um evento que cada vez que o usuario pressionasse tecla pra cima ou pra baixo pra selecionar o proximo registro ou o anterior, ele carregasse umas informações adicionais em baixo da tabela. ok até ai tudo bem, porem quando o usuario segura a tecla pra baixo continuamente, obrigando o programa a ir descendo rapidamente na tabela de clientes e fazendo muitos selects pra consultar esses dados adicionais, ocorre que em determinado ponto o postgres da um erro dizendo que há muitos usuários conectados(mesmo assim dando OK nesse erro ele continua funcionando normalmente).
Pelo que entendi cada vez que se faz um select ele não fecha a conexão, ficando com muitas conexões abertas na memória, mas como posso fazer pra fechar essas conexões? sendo que estou usando JDBC puro, sem framework, eu armazeno os resultados da consulta em um ResultSet.
A questão aqui é que está abrindo muitas requisições e fechando-as num período curto de tempo... eu acho válido um pool de conexões quando a aplicação é acessada por vários usuários fazendo várias coisas diferentes, mas veja só esse caso, é uma aplicação desktop, só um usuário vai estar usando. para que mais de uma conexão? Para que duas conexões ao mesmo tempo consultando duas linhas provavelmente seguidas da mesma tabela? Nesse caso eu sou a favor de manter uma conexão sim e reaproveita-la, mas concordo que singleton deve ser usado com cuidado, só onde seja ruim ter mais de um do mesmo recurso. Até acho viável usar algum framework como c3p0 para fechar uma conexão quando estiver inativo e abrir quando for usar mas não vejo onde algo assim precisa de mais de uma conexão. Usar mas de uma conexão ai não deveria ser necessário e demonstra que tem algum outro problema, só acho que você tem que fazer o máximo para fechar estas conexões assim que der se tiver muito usuário acessando ao mesmo tempo (centenas) essa base, o que é incomum em aplicação desktop mas se for para ficar fechar e reabrir logo em seguida ai ainda não vale a pema, se for usar duas conexões ao mesmo tempo para um só usuário ai que não vale a pena mesmo (isso seria meio desastroso com vários usuários ao mesmo tempo, pioraria ainda mais o problema).
Editando, o único caso onde vejo a necessidade de duas conexões para um único usuário é se ele estiver fazendo duas coisas ao mesmo tempo onde ambas precisam de uma conexão separada, mas não é bem esse o caso, seria por exemplo se o usuário puder deixar o sistema fazendo algo demorado que use o banco e possa fazer outras coisas enquanto o sistema faz isso em segundo plano por exemplo. Nesse caso procure usar um pool com a quantidade minima de requisições em um e verifique se não está indo para duas conexões sendo usadas quando não deveria.
Mateus outra dica que eu dou é que quando o usuário clicar na seta para baixo e você precisar pegar a próxima linha, não pegue uma linha só, pegue as próximas 50, 100, sei la, assim nas outras 49 você não precisa voltar la no banco. Acredito que as IDEs como o toad por exemplo fazem isso, inclusive se bem me lembro quando o usava, se você fizer isso bastante numa mesma consulta essa quantidade de linhas buscadas por vêz aumentava. Como o vini disse, feche seus recursos no finally.
Cláro que isso é só minha opinião (alias quando eu reparo que estou discordando do que o vinigodoy disse eu penso se não estou errado umas vezes... ).
This message was edited 1 time. Last update was at 05/01/2012 08:06:05
|
espero ter ajudado...
falando nisso, caso seu problema tenha sido resolvido, edite o seu primeiro post e coloque um [RESOLVIDO] no titulo do tópico.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 05/01/2012 07:59:18
|
Tchello
GUJ Master
![[Avatar]](/images/avatar/901db33c84e81b1a30e59949bbcb112b.png)
Membro desde: 07/06/2008 14:41:04
Mensagens: 1695
Offline
|
Epa, calma ae.
Eu disse uma conexão por transação, ou seja, quando precisar executar algo no banco abre uma conexão, usa tudo que precisa e quando não precisar mais fecha-la.
Não uma conexão por consulta. As coisas mudam bastante com isso.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 05/01/2012 08:26:31
|
maior_abandonado
JWizard
![[Avatar]](/images/avatar/0d7c463832b871c20405a6c9296b5517.jpg)
Membro desde: 03/09/2007 11:30:08
Mensagens: 2694
Localização: sp
Offline
|
Tchello wrote: Epa, calma ae.
Eu disse uma conexão por transação, ou seja, quando precisar executar algo no banco abre uma conexão, usa tudo que precisa e quando não precisar mais fecha-la.
Não uma conexão por consulta. As coisas mudam bastante com isso.
isso não se aplica no caso em questão (se eu intendi direito o que você disse, é claro), cada consulta é feita em separado da outra e inclusive elas nem precisam de uma transação aberta, nesse caso não da para abrir a conexão, fazer o que tiver que fazer e depois fechar. Se for ver bem se essa aplicação tiver um pool de 5, 10 conexões (sei la) e o usuário deixar a seta para baixo pressionada ao invés de abrir várias conexões iria abrir só 5 nesse caso que ele tem (ainda não está bom). Ainda acho que multiplas conexões numa aplicação desktop só podem ser usadas em processamento paralelo (e não é esse o caso). Nesse caso, caso a mesma tela precisa de outra coenxão para fazer a mesma coisa, provavelmente deveria haver um refactor para aproveitar a mesma para fazer isso na mesma consulta, no pior dos casos aguardar a conexão liberar e usa-la (eu vejo multiplos usuários tendo multiplas conexões algo que deve fortemente ser evitado, isso sim abriria muitos recursos na base, por isso nesse caso acho que o pool exige mais cuidado que o singleton, o que é beeeem irônico, cada caso é um caso).
This message was edited 1 time. Last update was at 05/01/2012 08:27:22
|
espero ter ajudado...
falando nisso, caso seu problema tenha sido resolvido, edite o seu primeiro post e coloque um [RESOLVIDO] no titulo do tópico.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 05/01/2012 08:37:40
|
mauricioadl
GUJ Master
![[Avatar]](/images/avatar/0958560bd45062d115debadb6bca3183.png)
Membro desde: 10/05/2007 14:52:21
Mensagens: 1140
Offline
|
concordo com o maior_abandonado:
1- o contexo em questao facilitaria uma unica conexao, e fecha-la apenas qndo nao houver atividade.
2 - se minha opniao confronta com a do vini, repenso meus conceitos.
concodo com o vini:
1 - concordo q eh ma pratica manter a regra dentro do banco, mas se for um ERP, por exemplo, o ganho eh esmagador devido a qntidade de acesso. e tbm eh mais facil achar profissionais de PL/SQL q eh o caso em q vivo do q profissionais de Java. (Isso onde moro, nao sei onde vcs moram)
2 - o oracle gerencia as conexoes pelo statement, criando um pool proprio para suas requisiçoes, acho que o sql server tbm faz isso
3 - verificar se a conexao esta ativa antes de usar, nao gera problema. um sigleton cai bem nisso.
This message was edited 1 time. Last update was at 05/01/2012 08:39:31
|
Seu problema foi resolvido? Por favor, edite seu primeiro post e adicione [RESOLVIDO] no título.
O forum agradece. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 05/01/2012 08:48:58
|
ViniGodoy
Moderador
![[Avatar]](/images/avatar/1921493b5362e63fbe8983f4bd54157d.png)
Membro desde: 11/12/2006 08:22:01
Mensagens: 20587
Localização: Curitiba/PR
Offline
|
A questão é que com o Pool, você usa o idioma de abrir e fechar por consulta, mas o pool evita a abertura e fechamento, reusando uma conexão. Fechar uma conection é uma operação que passa a ser substituída por "devolver ao pool".
Na prática, numa aplicação bem feita, você acaba com uma conexão aberta o tempo todo do mesmo jeito. A vantagem é que ele pode matar a conexão mais rapidamente caso o usuário deixe o sistema aberto e se recuperar caso o banco caia.
E outro detalhe é que ele é ridiculamente fácil de configurar, ao ponto de você ter que pensar três ou quatro vezes se não quer mesmo usa-lo. É quase tão fácil quanto escrever sua classe Singleton.
|
@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 |
|
|
 |
|
|
|
|