(otimização no java)Problema muito estranho com ResultSet fechado do postgresql
11 respostas
R
renatoAlves
Olá :-)
Estou com um probleminha muitoooo estranho :( . Já executei métodos parecidos com o abaixo e funcionam, mas com esse não :C
não sei porque =/. Lembrando que cada vez que eu executo um método de uma classe, após não ter nenhum método mais daquela classe para ser executado eu chamo o método "fechaconexao()", que citei ali embaixo. Só que quando executo este método(select_link) acusa o erro de ResultSet fechado.
Alguém tem um sugestão de como arrumar isso ou outra alternativa?
Já tentei abrir uma conexão para cada método de uma classe, porém fica muito lento no meu bando de dados, eu teria que ter uma conexão para cada classe no máximo.
Obrigado \o.
--
Tenho um método que chama:
link_ctrl lic = new link_ctrl();
ResultSet rs = lic.select_link("NULL");
(o rs acusa erro de result set fechado)
--
classlink_ctrl{StringSQL;Conexaoconex;Connectioncon=null;Statementstm=null;ResultSetrs=null;publiclink_in_ctrl(){conex=newConexao();try{con=conex.getConexao();}catch(SQLExceptione1){// TODO Auto-generated catch blocke1.printStackTrace();}try{stm=con.createStatement();}catch(SQLExceptione1){// TODO Auto-generated catch blocke1.printStackTrace();}}publicResultSetselect_link(Stringroot_url){ResultSetrs=null;SQL="SELECT idlink,url_complete FROM link where root_url is "+root_url+"";try{rs=stm.executeQuery(SQL);}catch(SQLExceptione){// TODO Auto-generated catch blocke.printStackTrace();}returnrs;}publicvoidfechaconexao(){try{conex.destroyConnection(con);}catch(SQLExceptione){// TODO Auto-generated catch blocke.printStackTrace();}}}
Cara, seria melhor se postasse o trecho do código em que vc faz a chamada mas, estou postando um teste que eu fiz:
Connection:
packageteste_guj;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;/** * * @author gabriel.arcanjo */publicclassConnectionFactory{privatestaticStringdriver="org.postgresql.Driver";privatestaticStringURL="jdbc:postgresql://localhost:5432/postgres";//Vc tem que colocar o nome do seu banco. Vc coloca o localhost se o MySql estive na mesma maquina da aplicação, se não vc tem que colocar o ip do servidor de Dados.privatestaticStringUSE="root";// Geralmente é root a não ser que vc mudeprivatestaticStringSENHA="senha";//seu senhapublicstaticConnectiongetConnection()throwsClassNotFoundException,SQLException{Class.forName(driver);returnDriverManager.getConnection(URL,USE,SENHA);}publicstaticvoidcloseConnection(Connectionconn,Statementstmt,ResultSetrs){close(conn,stmt,rs);}publicstaticvoidcloseConnection(Connectionconn,Statementstmt){close(conn,stmt,null);}publicstaticvoidcloseConnection(Connectionconn){close(conn,null,null);}privatestaticvoidclose(Connectionconn,Statementstmt,ResultSetrs){try{if(rs!=null){rs.close();}if(stmt!=null){stmt.close();}if(conn!=null){conn.close();}}catch(Exceptione){}}}
Utilização:
packageteste_guj;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.util.logging.Level;importjava.util.logging.Logger;/** * * @author gabriel.arcanjo */publicclassMain{staticConnectionconn;staticStatementstmt;staticResultSetrs;publicstaticvoidmain(String[]args){try{conn=ConnectionFactory.getConnection();stmt=conn.createStatement();rs=stmt.executeQuery("SELECT * FROM agente_negocio");while(rs.next()){System.out.println("Nome->"+rs.getString("nome_fantasia"));}ConnectionFactory.closeConnection(conn,stmt,rs);conn=ConnectionFactory.getConnection();stmt=conn.createStatement();rs=stmt.executeQuery("SELECT * FROM agente_negocio");while(rs.next()){System.out.println("Nome->"+rs.getString("nome_fantasia"));}ConnectionFactory.closeConnection(conn,stmt,rs);}catch(ClassNotFoundExceptionex){Logger.getLogger(Main.class.getName()).log(Level.SEVERE,null,ex);}catch(SQLExceptionex){Logger.getLogger(Main.class.getName()).log(Level.SEVERE,null,ex);}}}
Lembre sempre, sempre fechar a conexão.
R
renatoAlves
ah sim claro,
mas meu problema é otimização. Não posso ficar criando uma conexão para cada método meu, porque isso deixa meu programa lento(abrindo e fechando conexão toda hora). Meu problema ali é tentar não criar a conexão em cada método, apenas no início da classe e utilizar para todos os métodos daquela classe, porém da resultset fechado.
kotonet_ga
Então feche apenas o ResulSet como segue no código:
packageteste_guj;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.util.logging.Level;importjava.util.logging.Logger;/** * * @author gabriel.arcanjo */publicclassMain{staticConnectionconn;staticStatementstmt;staticResultSetrs;publicstaticvoidmain(String[]args){try{conn=ConnectionFactory.getConnection();stmt=conn.createStatement();rs=stmt.executeQuery("SELECT * FROM agente_negocio");while(rs.next()){System.out.println("Nome->"+rs.getString("nome_fantasia"));}ConnectionFactory.closeConnection(null,null,rs);// conn = ConnectionFactory.getConnection();// stmt = conn.createStatement();rs=stmt.executeQuery("SELECT * FROM agente_negocio");while(rs.next()){System.out.println("Nome->"+rs.getString("nome_fantasia"));}ConnectionFactory.closeConnection(conn,stmt,rs);}catch(ClassNotFoundExceptionex){Logger.getLogger(Main.class.getName()).log(Level.SEVERE,null,ex);}catch(SQLExceptionex){Logger.getLogger(Main.class.getName()).log(Level.SEVERE,null,ex);}}}
R
renatoAlves
mas aí tenho outro problema
o postgres tem um máximo de conexões simultâneas. Não posso ficar só abrindo e fechando apenas o resultset.
O que eu estava fazendo:
Instancio uma classe controle que abre uma conexão
Utilizo os métodos dela e fecho a conexão
Quando vou instanciar outra classe controle(conforme postei no primeiro post) e crio uma nova conexão, da resultset fechado.
kotonet_ga
Bem, tenta criar a classe de conexão estática.
Pode também tentar criar um pool de conexão.
R
renatoAlves
como seria a classe de conexão estática? apenas os métodos que chamam a conexão serem estáticos?
eberson_oliveira
Você poderia implementar um sigleton. Algo assim:
publicclassConnectionFactory{privatestaticConnectionconnection;publicstaticConnectiongetConnection()throwsClassNotFoundException,SQLException{Class.forName("org.postgresql.Driver");if(connection==null){StringURL="jdbc:postgresql://localhost:5432/postgres"; String USE = "root"; String SENHA = "senha";connection=DriverManager.getConnection(URL,USE,SENHA);}returnconnection;}}
Assim você consegue garantir que só vai existir uma instância dessa conexão na sua aplicação e irá abrí-la apenas um vez (quando for realmente usá-la).
Se ainda assim o problema do ResultSet persistir, forneça mais informações para que possamos avaliar a situação.
[]s
Éberson
boneazul
Como voce esta usando jdbc ate onde eu lembro a sua lentidao ta devido a sempre instancia uma nova conexão…
o que da problema geralmente e que ninguem sabe o porque …é usar o mesmo statement pra diferentes resultset…
principalmente com 1 dentro do outro…
talvez esteja ai seu problema dele falar que o resultset ja está fechado.
teoricamente voce precisa usar apenas 1 conexão(seja ela o singleton ou não)…
singleton ajuda pois pode ser que outra pessoa pegue a conexão ja aberta o que consome menos recurso de instanciação…
pra cada resultset use seu proprio statement…quando for trabalhar com resultset dentro de resultset…
e feche a conexão no fim…