Pool de conexão + Swing [PGSQL+Singleton+Pool = Perfomance] + Classe Exemplo

21 respostas
RogerioK

Se faz necessário o uso de pool se tratando de aplicação swing?

21 Respostas

malucocelo

Uma coisa independe da outra.

ViniGodoy

Sim, por que não faria?

Sem o pool a aplicação ficará lenta, já que sempre que se faz uma consulta, você deve abrir e fechar uma conexão. Mesmo em rede local, uma conexão com o MySQL pode demorar mais de 1 segundo para ser aberta.

leonardobhbr

depende se voce tiver uma aplicação servidora em swing.

Agora se sua aplicação conectar no banco diretamente não pois o padrao e cada aplicação ter apenas uma conexão, e abrir ela ao iniciar a aplicação e fechar apenas ao encerrar

ViniGodoy

É muito fácil configurar um pool. Não há desculpas para não faze-lo.

É uma péssima pratica abrir uma conexão no início da aplicação e só fecha-la ao encerrar. As desvantagens são:

  1. Você pode ter problemas se o banco de dados fechar a conexão (e ele as vezes fecha);
  2. Você consome memória e recursos desnecessariamente;
  3. Não funciona em ambientes de multiplas threads;
  4. Não é escalável.

Na prática, ninguém deveria desenvolver assim. Isso só serve para trabalho de escola.
E olha lá.

leonardobhbr

É muito fácil configurar um pool. Não há desculpas para não faze-lo.

É uma péssima pratica abrir uma conexão no início da aplicação e só fecha-la ao encerrar. As desvantagens são:

  1. Você pode ter problemas se o banco de dados fechar a conexão (e ele as vezes fecha);
  2. Você consome memória e recursos desnecessariamente;
  3. Não funciona em ambientes de multiplas threads;
  4. Não é escalável.

Na prática, ninguém deveria desenvolver assim. Isso só serve para trabalho de escola.
E olha lá.

Como q faz um pool de conexão sendo que a aplicação é cliente?

Como eu disse apenas se existir um servidor onde o cliente conecta via socket, RMI, etc.

Outra tenho uma aplicação em SE cliente usando JPA+Hibernate so para eu instanciar meu entitymanager o hibernate demora 15 segundos para fazer a checagem com o banco de dados das namedQuerys etc. Como eu faria para cada select eu abrir e fechar a conexão

ViniGodoy

Ué, é para isso mesmo que serve o pool. Para que o abrir e fechar de conexões para aplicação representem abrir e fechar coisas no pool, não diretamente. Assim você terá pool conexões já abertas, que não levarão os tais 15 segundos. O pool se encarregará de reciclar as conexões, para evitar que caiam, e abrir mais de uma conexão, caso haja multiplas threads (mais do que o previsto), ou fazer essa thread esperar.

Em resumo, é o pool é quem vai gerenciar quando as conexões reais são abertas ou fechadas.
E dá para usar um pool perfeitamente em Java SE, em aplicações Swing.

Se a aplicação for um cliente de um servidor de aplicação (através de RMI), não faz nem sequer sentido falar em pool de conexões no cliente. O pool daí fica no servidor. Mas haverá um pool do mesmo jeito.

O que estou condenando é o pessoal que cria a famosa classe Conexao, singleton, e abre lá a conexão apenas uma única vez. Troque essa classe por uma que use um pool.

leonardobhbr

Ué, é para isso mesmo que serve o pool. Para que o abrir e fechar de conexões para aplicação representem abrir e fechar coisas no pool, não diretamente. Assim você terá pool conexões já abertas, que não levarão os tais 15 segundos. O pool se encarregará de reciclar as conexões, para evitar que caiam, e abrir mais de uma conexão, caso haja multiplas threads (mais do que o previsto), ou fazer essa thread esperar.

Em resumo, é o pool é quem vai gerenciar quando as conexões reais são abertas ou fechadas.
E dá para usar um pool perfeitamente em Java SE, em aplicações Swing.

Se a aplicação for um cliente de um servidor de aplicação (através de RMI), não faz nem sequer sentido falar em pool de conexões no cliente. O pool daí fica no servidor. Mas haverá um pool do mesmo jeito.

O que estou condenando é o pessoal que cria a famosa classe Conexao, singleton, e abre lá a conexão apenas uma única vez. Troque essa classe por uma que use um pool.

Voce concorda que ao criar um pool de conexão a sua aplicação controlorar as conexões com o banco de dados e nao o banco de dados que ira controlar?

Imagine que eu tenha um banco de dados em uma maquina servidor e tenho varios jar’s clientes um em cada maquina se eu fizer um pool de conexão nao iria adiantar de nada pois cada jar abriria apenas uma conexão e as conexões utilizadas pelos outros jar seria distintas.

pool funcionária para este caso apenas se fosse multi-threads, caso não seja não há pq existir um pool de conexão, é um tanque de guerra para matar um mosquito.

Pool de uma conexão so seria util para garantir que nunca caia a conexão?

Bem essa é minha opnião

RogerioK

Seguinte: é uma aplicação swing que conecta diretamente com o banco de dados no caso postgresql, atualmente tenho uma clase que para cada query abre a conexão e executa a query e a fecha para esse caso seria bom um pool?

leonardobhbr

Sim concerteza

RogerioK

Certo, bom eu tentei implementar aqui e não consegui, tem algum exemplo para me passar?

eu preciso de um DataSource?

ViniGodoy

Sim. Na verdade, faz tempo que a forma recomendada que inicializar uma conexão em Java é através do DataSource.
No caso, o que o pool faz é só substituir o seu DataSource por ele.

O primeiro passo para implementar um pool é também escolher um. Já sabe se vai trabalhar com C3P0 ou Jakarta DBCP?
Os dois tem documentações que explicam como fazer para dispara-los.

Imagine que eu tenha um banco de dados em uma maquina servidor e tenho varios jar’s clientes um em cada maquina se eu fizer um pool de conexão nao iria adiantar de nada pois cada jar abriria apenas uma conexão e as conexões utilizadas pelos outros jar seria distintas.

pool funcionária para este caso apenas se fosse multi-threads, caso não seja não há pq existir um pool de conexão, é um tanque de guerra para matar um mosquito.

Eu ainda uso o pool porque:

  1. Não existem aplicações que não sejam multi-thread hoje em dia (o Swing mesmo dispara uma thread secundária, é comum criar processamento em outras threads para desocupa-la);
  2. Você nunca sabe se amanhã ou depois um colega seu vai querer fazer processamento multi-thread;
  3. É ridiculamente fácil de usar, não pesa a aplicação e não tem desvantagens;
RogerioK

Sim. Na verdade, faz tempo que a forma recomendada que inicializar uma conexão em Java é através do DataSource.
No caso, o que o pool faz é só substituir o seu DataSource por ele.

O primeiro passo para implementar um pool é também escolher um. Já sabe se vai trabalhar com C3P0 ou Jakarta DBCP?
Os dois tem documentações que explicam como fazer para dispara-los.

Bom, não sei se estou falando abobrinha, mas é possivel fazer o pool somente com o driver jdbc do postgresql

http://jdbc.postgresql.org/documentation/84/ds-ds.html

aqui eu vi a configuração do ds, seria somente isso?

ViniGodoy

Legal, aparentemente ele tem um pool sim. E pra configura-lo é só usar da maneira indicada pelo link que vc mesmo postou.

Com o datasource na mão, é só chamar seu método para obter a conexão e ser feliz. :slight_smile:

RogerioK

ViniGodoy:
Legal, aparentemente ele tem um pool sim. E pra configura-lo é só usar da maneira indicada pelo link que vc mesmo postou.

Com o datasource na mão, é só chamar seu método para obter a conexão e ser feliz. :)

Vini Obrigado pela ajuda!

O metodo para fazer a conexão com o banco usando ds deve ser estático correto?

ViniGodoy

Normalmente sim, o método para obter a conexão é estático e sincronizado.
Ou então, no caso do desktop, o objeto que gerencia esse datasource é um Singleton.

RogerioK

Normalmente sim, o método para obter a conexão é estático e sincronizado.
Ou então, no caso do desktop, o objeto que gerencia esse datasource é um Singleton.

Consegui fazer, muito facil que até fiquei com vergonha de ter perguntado :oops:

O ganho de desempenho foi ótimo! antes dava para perceber que a aplicação ficava esperando um pouco em cada query, agora é tudo mais rápido!

Bom, não sei se está 100% certo a classe mas vou postar aqui caso alguem queira testar/usar

Singleton+PGPool

import java.sql.*;
import org.postgresql.ds.PGPoolingDataSource;

public class ConexaoPgsqlPool {
    public static ConexaoPgsqlPool myInstance;
    private static Connection connection = null;
    PGPoolingDataSource source = new PGPoolingDataSource();

    private ConexaoPgsqlPool(){
        source.setDataSourceName("PGSQLPOOL");
        source.setServerName(IP);
        source.setDatabaseName(DB);
        source.setUser(usuarioBanco);
        source.setPassword(senhaBanco);
        source.setMaxConnections(5);
    }

    public Connection abreConexao() throws SQLException{
        if(connection == null){
            connection = source.getConnection();
        }
        return connection;
    }

    public static ConexaoPgsqlPool getInstance(){
           if(myInstance == null) {
                myInstance = new ConexaoPgsqlPool();
           }
           return myInstance;
     }
}

Obrigado pela ajuda de todos!

ViniGodoy

Não falei que era moleza?
Fala a verdade, sendo tão fácil assim, sobram poucas desculpas para não usar um pool, não é mesmo?

Só lembre-se que agora é importante fechar as conexões sempre que utiliza-las. Pois o close simplesmente retornará a conexão para o pool.

RogerioK

ViniGodoy:
Não falei que era moleza?
Fala a verdade, sendo tão fácil assim, sobram poucas desculpas para não usar um pool, não é mesmo?

Só lembre-se que agora é importante fechar as conexões sempre que utiliza-las. Pois o close simplesmente retornará a conexão para o pool.

Muito facil que até fiquei com vergonha :oops:

Bom, mas mesmo usando Pool é necessário fechar as conexões?

ViniGodoy

Sim, mas o close() não fechará a conexão de verdade.
Ele só avisará ao pool que aquela conexão pode ser utilizada novamente.

É que funciona assim. Uma chamada ao getConnection() faz o pool entender que agora alguém está usando aquela conexão.
Se outra pessoa (normalmente outra Thread) chamar getConnection() no período, o pool abrirá uma segunda conexão.

Ele vai fazer isso em até 5 conexões simultaneas (seu MaxConnections).

Uma chamada ao close() avisa o pool que a conexão foi liberada. A conexão não é fechada, ela só volta ao pool e se alguém chamar getConnection() novamente, a conexão é reaproveitada. Por isso é importante chama-lo sempre, preferencialmente num bloco finally.

Verifique que a maioria dos pools tem um timeout. Esse timeout é o tempo que a conexão pode ficar ociosa no pool, sem que seja fechada de verdade. Muitos pools também tem um MinConnections, que é o número de conexões que vc quer que fiquem sempre abertas, esperando por você.

R

Rogério: creio que o seu problema já está resolvido, mas, caso você queira analisar, deixo a dica do C3P0:

http://www.mchange.com/projects/c3p0/index.html

É um pool de conexões maduro e cheio de recursos interessantes.

marciofermino

Amigos entendi mais acreditem NAO CONSEGUI RODAR..

tenho minha factory assim:
public static Connection getConnectionMysql() throws SQLException {
		try {
			
			Class.forName("com.mysql.jdbc.Driver");
			return DriverManager.getConnection(
					"jdbc:mysql://xxxxx.com.br/xxxx",
					"xxxxx", "xxxxx");

		} catch (ClassNotFoundException e) {
			throw new SQLException(e.getMessage());
		}
	}

Como ficaria utilizando POOL e como eu ganho a conexao??

con = (Connection) ConnectionFactory.getConnectionMysql();

Obrigado.

Criado 20 de janeiro de 2011
Ultima resposta 13 de abr. de 2011
Respostas 21
Participantes 6