Sql update trava a aplicação

20 respostas
D

pessoal, fiz uma série de updates mas nenhum deles funciona, simplesmente trava toda a aplicação e enm dá para saber o que é se não for no olho. Podem me ajudar?!
o que consigo fazer é fazer System.out.println() para saber até onde é executado, sou levado até o PreparedStatement, chogo aqui e não sei mais o que fazer…
o banco usado é o Derby

numa classe eu o chamo

daoEndereco.alterar(endereco);
public void alterar(Contato contato) throws SQLException{
                
                System.out.println("aa");
                String sql = "update contato set nome=? , segundonome=? , sobrenome=? , descricao=? where id=?";
                java.sql.PreparedStatement preparedStatement = dao.getConexao().prepareStatement(sql);
                System.out.println("bb");
                preparedStatement.setString(1, contato.getNome());
                preparedStatement.setString(2, contato.getSegundoNome());
                preparedStatement.setString(3, contato.getSobreNome());
                preparedStatement.setString(4, contato.getDescricao());
                preparedStatement.setLong(5, contato.getId());
                System.out.println("cc");
                preparedStatement.executeUpdate();
                System.out.println("dd");
        }

meu código trava na linha preparedStatement.executeUpdate(); não o executa pq não é alterado e nem o System.out.println(“dd”);
já conferi no banco as tabelas, elas estão ok.

20 Respostas

G

coloque seu código dentro de um try/catch para vc capturar o erro (printStackTrace)

Só um palpite, essa tabela pode estar “lockada” pela sua aplicação em algum ponto, por isso, trava.

Posta ai o stackTrace…

A

Será lock de tabela?

D

po… mesmo se eu fechar e abrir o netbenas e a primeira coisa a fazer é esse update, trava.
não exibe o stacktace, tenho que parar o aplicativo pelo netbeans, assim não é exibido nada.
ele trava justamente no executeUpdate().
já tentei execute() e acabei de testar com o Statement, fazendo um monte de concatenaçaõ e deu a mesma coisa.

P

daquinho:
po… mesmo se eu fechar e abrir o netbenas e a primeira coisa a fazer é esse update, trava.
não exibe o stacktace, tenho que parar o aplicativo pelo netbeans, assim não é exibido nada.
ele trava justamente no executeUpdate().
já tentei execute() e acabei de testar com o Statement, fazendo um monte de concatenaçaõ e deu a mesma coisa.

vc esta usando transação ?

está parecendo problema de lock!! alguma outra query, programa, usuario, tá segurando o seu update… ou algo similar

D

po, acho que não, uso o Derby Embedded, fecho e abro o netbeans e nada.

obs:
o mesmo sql usado no Squirrel-SQL(gerenciador genérico de sql) funciona.
mesmo fechando o squirrel não rola, sei que trava quando já tem um acesso aberto, tanto que deletar e add funcionam, mas o update é o que me falta fazer funcionar.

D

vc esta usando transação ?
está parecendo problema de lock!! alguma outra query tá segurando o seu update… ou algo similar

saquei… eu já tinha procurado por isso, mas não encontrei.
olha… to esperadno que com o fim de um método , o que tenho em uso se feche, outra, tenho criado os objetos auxiliares de acesso ao banco nos proprios métodos, como o statement, preparedStatement, resultSet e tal, menos o meu Dao que loga e cria a conexão que é único para todos.

public Connection getConexao(){
                
                String url = carregarPropriedades().getProperty("banco.url");
                String user = carregarPropriedades().getProperty("banco.user");
                String password = carregarPropriedades().getProperty("banco.password");
                String driver = carregarPropriedades().getProperty("banco.driver");
                try {
                        if(connection == null){
                                Class.forName(driver);
                                connection = DriverManager.getConnection(url, user, password);
                        }
                }
                catch (ClassNotFoundException ex) {
                        ErroAgenda.exibirMensagemErro(ex);
                }
                catch (SQLException ex){
                        ErroAgenda.exibirMensagemErro(ex);
                }

                return connection;
        }

vou conferir os métodos que carregam altes de eu usar o update para ver se todos estão de acordo com o que descrevi acima, pois com o tempo fiz muitas alterações, inclusive como teste e erros q iam aparecendo.

D

não estou usando hibernate e afins, tudo namão(stou preferindo assim por enquanto).
como devo fazer para garantir uma transação? como deve ficar o meu código? o que estou fazendo é chamar sempre o DAO, se já aexistir não crio nova conexão, por ele faço:
dao.createPreparedStatement();

ao fim do método(na classe DAO) eu estava adotando o seguinte:
private void fecharConexao(){
                    statement = null;
                    connection = null;
        }

e nas classes que usam o dao, como contatoDao(como o q tem lá em cima em outro post), eu usava para fechar..
[code]
private void fecharPropriedades(){
dao = null;
java.sql.PreparedStatement preparedStatement = null;
java.sql.ResultSet resultSet = null;
}

o dao recebe null, pq nessas classes ele é uma propriedade, então sempre que declaro uma classe contatoDAo, ele é criado com uma conexão pronta para ser usada.

P

intão vc não pode deixar sua conexão aberta, vc tem que fechar elas invocando o método close(), tanto da connection quanto do statement, antes de atribuir null, se vc precisaar fazer outra query vc cria outra conexão, não deve utilizar a mesma!!
exemplo:

private void fecharConexao(){ statement .close() ; statement = null; connection.close(); connection = null; }

sobre a transção vc ñ tá usando, pensei no começo que tava usando hibernate…mais entendi errado…

D

oi pessoal, estava atarefado, por isso dei uma sumida…
é… não estou usando hibernate, por enquanto não.

tenho que usar close() e depois atribuir null? os dois?
tinha uma mistureba, então fui de método em método conferir e alterei todas que necessário, declarando e atribuindo sempre dentro dos métodos, as classes que direta ou indiretamente fazem acesso ao banco(isso dentro das DAOs claro!!!) e ao fim desses métodos sempre atribuindo null, certo?

ainda não terminei, daqui apouco termino e posto aqui,
vlw.

D

po, nada feito, olhem um exemplo, desse jeito que declaro, instâncio e fecho em todos os métodos.

public Contato buscarContato(long id) throws SQLException{

            Dao dao = new Dao();
            java.sql.ResultSet resultSet = null;
            java.sql.PreparedStatement preparedStatement = null;
            Contato contato = new Contato();
            
            String sql = "select * from contato where id=?";

            preparedStatement = dao.getConexao().prepareStatement(sql);
            preparedStatement.setLong(1, id);
            resultSet = preparedStatement.executeQuery();
            resultSet.next();
                contato.setId(id);
                contato.setNome(resultSet.getString(2));
                contato.setSegundoNome(resultSet.getString(3));
                contato.setSobreNome(resultSet.getString(4));
                contato.setDescricao(resultSet.getString(5));

        dao = null;
        preparedStatement = null;
        resultSet = null;

            return contato;
    }
D

pessoal, muito obrigado.

adicionei um monte de close() nos objetos e funcionou… que bobeira a minha.

pessoal, se o objeto é declarado e instânciado dentro do método, não era para ele ser recolhido pelo garbageCollector quando esse método não é mais usado?

P

daquinho, o garbagecolector só recolhe os objetos que não tem nenhuma referencia, ou seja se tiver null…
Porem o GC apenas remove da memoria, ele não chama o método close… vc que tem que chamar…
vc precisa chamar pois a conexão esta aberta com outra maquina(Servidor) c vc setar null o GC ira recolher, mais a conexão com a outra maquina vai ficar aberta do outro lado… c vc chamar o close antes do null, ai sim a implementação do método ira encerrar as conexões com ambas as maquinas…

D

então o melhor é fazer close() e em seguida null tb? os dois???
mesmo que eu crie um objeto dentro do método e no final setar null, ainda vai existir uma conexão com o banco… estranho, mas se funcional, não tenho como ainda duvidar, só a osmose que não está completa, depois tudo se encaixa…rsrs.

P

é q vc ainda num entendeu direito…
dentro do metodo c vc criar uma instancia, esta instancia ira ser recolhida pelo GC quando o metodo finalizar (a ñ ser c vc retornar esta instancia para outro lugar), como vc disse, porem o CG só ira apagar da mémoria ñ ira fazer nada alem disso.

Só que quando vc esta fazendo uma conexão com uma base de dados, na verdade existem 2 progrmas se comunicando com uma conexão(servidor, cliente), se o GC levar seu objeto do seu programa(programa cliente) que esta com a conexão, o outro programa(servidor) vai ficar avida toda com a conexao aberta esperando o fim da conexão, pois só ira encerrar quando vc dizer para encerrar, q neste caso é o método close

Vc precisaria entender um pouco mais como funciona a conexão com 2 programas, ou maquinas.

depente… se sua instancia for criada dentro do metodo vc só precisaria chamar o close
Exemplo

class a{
    public void buscaNoBanco(){
       Dao dao = new Dao();
       dao.getConnect().executeQuery(blabla);
       dao.close();//isso basta, encerrando a conexão com o servidor. ambos fechando conexão
}//aqui o CG ira recolher da memoria a instancia dao
}

Agora se sua instancia estiver na classe ai teria que fechar e setar null para liberar o recurso…
Exemplo:

class a{ 
      private Dao dao;
      public void buscaNoBanco(){
       dao = new Dao();
       dao.getConnect().executeQuery(blabla);
       dao.close();//isso basta, encerrando a conexão com o servidor. ambos fechando conexão
dao = null;//aqui o CG ira recolher da memoria a instancia dao se não setar null ira ficar na memoria ate sua classe 'a' morrer

}
public static void main(String args[]){
 a a = new a();
a.buscaNoBanco();
dao}
}
A

Está parecendo que você não usa pool de conexão, essa idéia é muito bacana…

D

é q vc ainda num entendeu direito…
dentro do metodo c vc criar uma instancia, esta instancia ira ser recolhida pelo GC quando o metodo finalizar (a ñ ser c vc retornar esta instancia para outro lugar), como vc disse, porem o CG só ira apagar da mémoria ñ ira fazer nada alem disso.

Só que quando vc esta fazendo uma conexão com uma base de dados, na verdade existem 2 progrmas se comunicando com uma conexão(servidor, cliente), se o GC levar seu objeto do seu programa(programa cliente) que esta com a conexão, o outro programa(servidor) vai ficar avida toda com a conexao aberta esperando o fim da conexão, pois só ira encerrar quando vc dizer para encerrar, q neste caso é o método close

Vc precisaria entender um pouco mais como funciona a conexão com 2 programas, ou maquinas.

po cara, SHOW de bola a explicação, já bastava a pequena explicaçaõ no inicio e com o código mais ainda.
tinha esquecido, SGDB, e não um arquivinho simples…
muito obrigado.

D

pool de conexão é verificar antes de usar se ja´existe esse objeto declarado e instânciado?

Connection connection; if(connection = null) connection = DriveManager(url,login,senha); é isso?

A

Não, o pool de conexão é uma forma de você melhorar a criação das conexões com o banco

Você criar várias conexões quando a sua aplicação inicia por exemplo e armazena no pool, quando você precisa de uma conexão vai no pool e busca uma (que já foi criada anteriormente) quando você não precisa mais da conexão você devolve ela para o pool (não destrói a conexão mais)

Existem várias formas de você criar um pool, pode ser na mão, pode ser usando um servidor (como tomcat, weblogic, etc)

D

hummm, um repositório de conexões já criadas, a cada conexão pego uma e depois devolvo… isso deve dar algum desempenho e organização né!!!
eu já tenho a idéia firmada de sempre criar e desfazer as conexões sempre que precisar ir ao banco, no início sempre pensava que deveria ficar alguma coisa sempre aberta, mas já vi que não é assim.
Mas também pensando sempre em desempenho, se criar sempre e destruir os objetos que vão sempre ser criados, se isso não afeta a velocidade do aplicativo?

P

não… o conceito de pool de conexões é este:
Quando vc conecta em um banco de dados vc cria uma conexão com o servidor. Até ai normal, porem quantas vezes sua aplicação ira conectar no banco ?
Praticamente a todo instante, certo ?. Este processo de criar conexão é um processo lento pois envolve a rede e outros recursos da maquina, ao inves de vc criar uma conexão cada hora q vc precisar, vc criaria varias conexões e deixaria guardada para usar quando vc precisar, assim vc teria varias conexõs disponiveis ao inves de ficar criando uma a cada momento q vc precisar… no java já existe pronto, bastando apenas configurar, a classe chama-se DataSource q vc pode obter via JNDI… tem bastante coisa pra aprender, tai um bom assunto para vc estudar a fundo, use o google tem muita coisa sobre pool de conexões na net pra java…
Segue uma:
http://www.guj.com.br/java/194426-pool-de-conexoes

Criado 1 de março de 2011
Ultima resposta 4 de mar. de 2011
Respostas 20
Participantes 5