Swing Lento ao Conectar no Mysql (via Rede)

7 respostas
mateus.cordeiro

Senhores,

Bom dia

Estou com um problema na lentidão de uma aplicação que faz algumas veririfcações.
Como esse é meu primeiro projeto que está indo para produção, e eu não tenho ninguém na empresa que pode me ajudar, então conto com a cooperação de todos.

Eu estou fazendo uma aplicação que vai fazer a marcação do ponto dos funcionarios.
Porem não sei o que acontece, mas na maquina que estou fazendo o desenvolvimento está perfeito, super rapido sem problemas.
Só que quando tento conectar no server(linux) da empresa(onde está instalado o banco mysql), fica muito lento (+ou- uns 30 segundos p/ responder).

Só que o cara que cuida da infra aqui, ta dizendo que estou criando muitas conexões no banco e é isso que esta prejudicando.

Então estou perdido, não sei o que fazer.
Estou colocando os codigos de conexao para que puder me ajudar, muito obrigado.

Classe Conexao
public class ConexaoDB { 
  
    private static final String URL_MYSQL = "jdbc:mysql://192.168.8.4/controlehoras";  
    private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";  
    private static final String USER = "mateus";  
    private static final String PASS = "102030";  
   
     public static Connection getConnection() {  

        System.out.println("Conectando ao Banco de Dados");  

         try {  
            Class.forName(DRIVER_CLASS);  
            return DriverManager.getConnection(URL_MYSQL, USER, PASS);  
        } catch (ClassNotFoundException e) {  
           e.printStackTrace();  
        } catch (SQLException e) {  
            throw new RuntimeException(e);  
        }  
        return null;  
     }  
}
Classe que faz o gerenciamente do DAO
public abstract class GenericDao {
     private static Connection connection;

    protected GenericDao() {
	this.connection = ConexaoDB.getConnection();
    }

    protected Connection getConnection() {
        return connection;
    }

    protected void save(String insertSql, Object... parametros) throws SQLException {
        PreparedStatement pstmt = connection.prepareStatement(insertSql);

        for (int i = 0; i < parametros.length; i++) {
		pstmt.setObject(i+1, parametros[i]);
        }

	pstmt.execute();
	pstmt.close();
        System.out.println("Conexão Fechada");
    }
    
    protected void update(String updateSql,Object... parametros) throws SQLException {
	PreparedStatement pstmt = connection.prepareStatement(updateSql);
	for (int i = 0; i < parametros.length; i++) {
                pstmt.setObject(i+1, parametros[i]);
	}
	pstmt.executeUpdate();
        pstmt.close();
        System.out.println("Conexão Fechada");
    }

    protected void delete(String deleteSql, Object... parametros) throws SQLException {
	PreparedStatement pstmt = connection.prepareStatement(deleteSql);
	for (int i = 0; i < parametros.length; i++) {
                pstmt.setObject(i+1, parametros[i]);
	}

	pstmt.execute();
	pstmt.close();
    }
}
Classe que faz a validação dos users:
public class ValidarLogin {
    
        //Variavel global para idusuario
        private static int varUser ;
        public static void setVarUser(int arg)  {  
               varUser = arg;  
        }  
        public static int getVarUser()    {  
               return varUser;  
        }
        
        //Verifica se o usuario está correto no banco e seu senha        
        public static Usuario validar(String nome, String senha) throws SQLException {
            String select = "SELECT idusuario FROM usuario WHERE nome = ? and senha = ?";
            Usuario usuario = null;
                
                
                PreparedStatement stmt = ConexaoDB.getConnection().prepareStatement(select);
                stmt.setString(1,nome);
                stmt.setString(2,senha);
                ResultSet rs = stmt.executeQuery();
                        

            if (rs.next()){
                usuario = new Usuario();
                usuario.setIdusuario(rs.getInt("idusuario"));
                //Setando a variavel global
                ValidarLogin.setVarUser(usuario.getIdusuario());
                System.out.println("IdUsuario = " + ValidarLogin.getVarUser());
            }else{
                usuario = new Usuario();
                usuario.setIdusuario(0);
            }

            rs.close();
            System.out.println("Conexão Fechada");
            //stmt.close();
            return usuario;
        }
        
        
        public Usuario verificaUsuario(int idusuario) throws SQLException {
            String select = "SELECT idusuario FROM usuario WHERE idusuario = ?";
            Usuario usuario = null;
            PreparedStatement stmt = ConexaoDB.getConnection().prepareStatement(select);
            stmt.setInt(1,idusuario);
            ResultSet rs = stmt.executeQuery();
            //teste
            
            
            //if (rs.next()){ 
            if (rs.first()){ //testando First em vez de Next -- Ok funfa!
                usuario = new Usuario();
                usuario.setIdusuario(rs.getInt("idusuario"));
            }else{
                //usuario = new Usuario();
                return null;
            }
            rs.close();
            stmt.close();
            return usuario;
        }
        
        public String retornaNome(int idusuario) {
            String select = "SELECT nome_completo FROM usuario WHERE idusuario = ?";
            //Usuario usuario = null;
            String nomec = null;
           try{
            PreparedStatement stmt = ConexaoDB.getConnection().prepareStatement(select);
            stmt.setInt(1,idusuario);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()){
                //usuario = new Usuario();
                nomec = rs.getString("nome_completo");
            }
            
            rs.close();
            stmt.close();
            return nomec;
           }catch (SQLException e){
               System.out.println("erro no metodo retornaNome da classe ValidarLogin");
           }return nomec;
        }
        
        public String retornaEntrada(int idusuario) {
            String select = "SELECT entrada FROM tabcontrole WHERE  cod_func = ? and data_cont = curdate()";
            //Usuario usuario = null;
            String entradaUser = null;
           try{
            PreparedStatement stmt = ConexaoDB.getConnection().prepareStatement(select);
            stmt.setInt(1,idusuario);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()){
                //usuario = new Usuario();
                entradaUser = rs.getString("entrada");
            }
            
            rs.close();
            stmt.close();
            return entradaUser;
           }catch (SQLException e){
               System.out.println("erro no metodo retornaNome da classe ValidarLogin");
           }return entradaUser;
        }
        
        public String retornaSaida(int idusuario) {
            String select = "SELECT saida FROM tabcontrole WHERE  cod_func = ? and data_cont = curdate()";
            //Usuario usuario = null;
            String entradaUser = null;
           try{
            PreparedStatement stmt = ConexaoDB.getConnection().prepareStatement(select);
            stmt.setInt(1,idusuario);
            ResultSet rs = stmt.executeQuery();

            if (rs.first()){
                //usuario = new Usuario();
                entradaUser = rs.getString("saida");
            }
            
            rs.close();
            stmt.close();
            return entradaUser;
           }catch (SQLException e){
               System.out.println("erro no metodo retornaNome da classe ValidarLogin");
           }return entradaUser;
        }
        
        public String retornaAlmoco(int idusuario) {
            String select = "SELECT almoco FROM tabcontrole WHERE  cod_func = ? and data_cont = curdate()";
            String entradaUser = null;
           try{
            PreparedStatement stmt = ConexaoDB.getConnection().prepareStatement(select);
            stmt.setInt(1,idusuario);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()){
                entradaUser = rs.getString("almoco");
            }
            
            rs.close();
            stmt.close();
            return entradaUser;
           }catch (SQLException e){
               System.out.println("erro no metodo retornaNome da classe ValidarLogin");
           }return entradaUser;
        }
        
        public String retornaVolta(int idusuario) {
            String select = "SELECT volta FROM tabcontrole WHERE  cod_func = ? and data_cont = curdate()";
            String entradaUser = null;
           try{
            PreparedStatement stmt = ConexaoDB.getConnection().prepareStatement(select);
            stmt.setInt(1,idusuario);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()){
                entradaUser = rs.getString("volta");
            }
            
            rs.close();
            stmt.close();
            return entradaUser;
           }catch (SQLException e){
               System.out.println("erro no metodo retornaNome da classe ValidarLogin");
           }return entradaUser;
        }
 
}

Obrigado!

7 Respostas

ViniGodoy

Seu código, do jeito que está, só abre conexões, nunca as fecha.
Para resolver:

  1. Use um pool de conexões (C3P0 ou DBCP);
  2. Use um framework que garanta que conexões serão fechadas (Spring ou Hibernate).
    Ou então, acrescente no “finally” o fechamento de conexões, statement e resultsets sempre.
  3. Dê uma lida nesse artigo do Brian Goetz: http://www.ibm.com/developerworks/java/library/j-jtp03216/index.html
Ironlynx

private static final String USER = "mateus"; private static final String PASS = "102030";
Mateus, além das dicas do Vini, seria interessante vc controlar o acesso dos usuários, para evitar múltiplos logins e uso desnecessário de recursos do sistema.As vezes, fazer uma simples tabelinha de controle de usuários já ajuda, se vc não está usando algo que faça isso para vc(Hibernate…).

As informações abaixo ajudam:
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html

mateus.cordeiro

Vini
Vou usar o hibernate, porem o projeto está atrasado.
Fiz alguns testes na rede, montei um xp e instalei o MySql.
Ficou perfeito, super rapido e tranquilo!
Não sei se o problema estava no servidor Linux que estava o banco!
Só esta com esse problema mesmo de ficar conexões pinduradas.

Vou continuar trabalhando para melhorar essa aplicação.

Obrigado a todos

mateus.cordeiro

To tentando criar a classe pool para conexao.
Mas nao estou conseguindo.

O que está errado?

import java.sql.*;   
import org.apache.commons.dbcp.BasicDataSource;
  
public class PoolConexao {   
    public static PoolConexao myInstance;   
    private static Connection connection = null;   
    BasicDataSource source = new BasicDataSource();
  
    private PoolConexao(){   
        source.setDriverClassName("com.mysql.jdbc.Driver");
        source.setUsername("root");   
        source.setPassword("root");   
        source.setUrl("jdbc:mysql://localhost/controlehoras");   
        source.setInitialSize(10);//Seta o pool para apenas uma conexão ativa   
        source.setMinIdle(10);//Obriga o pool a ter pelo menos uma conexão sempre ativa   
        source.setTestOnReturn(true);//Habilita o teste da conexão antes de retorná-la   
        source.setValidationQuery("SELECT sysdate() FROM dual");
    }   
  
    public Connection abreConexao() throws SQLException{   
        if(connection == null){   
            connection = source.getConnection();   
        }   
        return connection;   
    }   
  
    public static PoolConexao getInstance(){   
           if(myInstance == null) {   
                myInstance = new PoolConexao();   
           }   
           return myInstance;   
     }   
    
    public void showStatusDataSource(){   
        System.out.println("Conexões ativas: "+source.getNumActive());   
        System.out.println("Conexões inativas: "+source.getNumIdle());   
    }
    
    public static void main (String [] args){
    PoolConexao p = new PoolConexao();
    p.showStatusDataSource();
    }
}
FernandoFranzini

O problema da lentidão não o swing e sim seu código de acesso, rede Favor reveja as praticas de JDBC básicas.
Rede, e limitações no servidor SGDB tb podem gerar problemas de performance.

mateus.cordeiro

Fernando
Não entendi o que vc disse!“Favor reveja as praticas de JDBC básicas”! (Dá uma dica do que está errado).

Mas a questão da lentidão resolveu, estou tentando melhorar a aplicação por usar pool de conexao, conforme indicado pelo Vini!

Ajuda ae!

FernandoFranzini
Criado 3 de novembro de 2011
Ultima resposta 4 de nov. de 2011
Respostas 7
Participantes 4