Oracle 10g - Cursores abertos

2 respostas
Saeger

Olá pessoal,

Estou com o seguinte problema: Os cursores abertos no Oracle nunca são fechados.
Pesquisando no fórum da Oracle a única referência que encontrei é a seguinte:

https://forums.oracle.com/forums/thread.jspa?threadID=685197

Fiz um exemplo que funciona da seguinte maneira:

public class OracleApplicationTest {

  public static void main(String[] args) throws Exception {
    Class.forName("oracle.jdbc.driver.OracleDriver");
    Connection con = DriverManager.getConnection("jdbc:oracle:thin:@SERVIDOR:1522:ORCL10", "BUGS", "SENHA");

    ResultSet rs = null;
    PreparedStatement stmt = con.prepareStatement("select * from tabela");

    rs = stmt.executeQuery(); //Abre 1 cursor neste momento.

    ResultSet rs2 = null;
    PreparedStatement stmt2 = con.prepareStatement("select * from tabela");

    rs2 = stmt2.executeQuery(); //Abre 1 cursor neste momento.

    ResultSet rs3 = null;
    PreparedStatement stmt3 = con.prepareStatement("select * from tabela");

    rs3 = stmt3.executeQuery(); //Abre 1 cursor neste momento.

    rs3.close();
    stmt3.close();
    rs2.close();
    stmt2.close();
    rs.close();
    stmt.close();

    Runtime rt = Runtime.getRuntime();
    rt.gc();
    Runtime rt2 = Runtime.getRuntime();
    rt2.gc();
    Runtime rt3 = Runtime.getRuntime();
    rt3.gc();
    
    con.close();
  }
Se você executar o código (especificando sua base, usuario e senha), você vai ver que os cursores não são fechados. Apenas no momento que a conexão é fechada (con.close()). Observação: -O motivo do uso do garbage collector, foi uma tentativa de fazer com que ele eliminasse a classe a os cursores fossem fechados. Mas sabemos que não há garantia do GC ser feito no momento em que queremos. -O driver é o mais atualizado (ojdbc5.jar) Manifest:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_24-rev-b08 (Sun Microsystems Inc.)
Implementation-Vendor: Oracle Corporation
Implementation-Title: JDBC
Implementation-Version: 11.2.0.2.0
Repository-Id: JAVAVM_11.2.0.2.0_LINUX_100812.1
Specification-Vendor: Sun Microsystems Inc.
Specification-Title: JDBC
Specification-Version: 4.0
Main-Class: oracle.jdbc.OracleDriver
sealed: true

Name: oracle/sql/converter/
Sealed: false

Name: oracle/sql/
Sealed: false

Name: oracle/sql/converter_xcharset/
Sealed: false

Alguem já passou por um problema semelhante ? Vamos discutir...

2 Respostas

maior_abandonado
Saeger:
Olá pessoal,

Estou com o seguinte problema: Os cursores abertos no Oracle nunca são fechados.
Pesquisando no fórum da Oracle a única referência que encontrei é a seguinte:

https://forums.oracle.com/forums/thread.jspa?threadID=685197

Fiz um exemplo que funciona da seguinte maneira:

public class OracleApplicationTest {

  public static void main(String[] args) throws Exception {
    Class.forName("oracle.jdbc.driver.OracleDriver");
    Connection con = DriverManager.getConnection("jdbc:oracle:thin:@SERVIDOR:1522:ORCL10", "BUGS", "SENHA");

    ResultSet rs = null;
    PreparedStatement stmt = con.prepareStatement("select * from tabela");

    rs = stmt.executeQuery(); //Abre 1 cursor neste momento.

    ResultSet rs2 = null;
    PreparedStatement stmt2 = con.prepareStatement("select * from tabela");

    rs2 = stmt2.executeQuery(); //Abre 1 cursor neste momento.

    ResultSet rs3 = null;
    PreparedStatement stmt3 = con.prepareStatement("select * from tabela");

    rs3 = stmt3.executeQuery(); //Abre 1 cursor neste momento.

    rs3.close();
    stmt3.close();
    rs2.close();
    stmt2.close();
    rs.close();
    stmt.close();

    Runtime rt = Runtime.getRuntime();
    rt.gc();
    Runtime rt2 = Runtime.getRuntime();
    rt2.gc();
    Runtime rt3 = Runtime.getRuntime();
    rt3.gc();
    
    con.close();
  }
Se você executar o código (especificando sua base, usuario e senha), você vai ver que os cursores não são fechados. Apenas no momento que a conexão é fechada (con.close()). Observação: -O motivo do uso do garbage collector, foi uma tentativa de fazer com que ele eliminasse a classe a os cursores fossem fechados. Mas sabemos que não há garantia do GC ser feito no momento em que queremos. -O driver é o mais atualizado (ojdbc5.jar) Manifest:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_24-rev-b08 (Sun Microsystems Inc.)
Implementation-Vendor: Oracle Corporation
Implementation-Title: JDBC
Implementation-Version: 11.2.0.2.0
Repository-Id: JAVAVM_11.2.0.2.0_LINUX_100812.1
Specification-Vendor: Sun Microsystems Inc.
Specification-Title: JDBC
Specification-Version: 4.0
Main-Class: oracle.jdbc.OracleDriver
sealed: true

Name: oracle/sql/converter/
Sealed: false

Name: oracle/sql/
Sealed: false

Name: oracle/sql/converter_xcharset/
Sealed: false

Alguem já passou por um problema semelhante ? Vamos discutir...

pessoalmente eu acho estranho isso ter acontecido... "se" não deu nenhum erro e passou pelas linhas de onde chama os métodos close, deveria ter fechado estes cursores sim...

quanto ao gc não ter feito diferença, ele limparia estes objetos mas a referencia a eles ainda persiste, se você quer que ele remova os objetos eu te diria para atribuir null as variáveis stmt e rs que você tem antes de chamar o gc, ou melhor, fazer esse teste em um método chamado pelo main e chamar o gc no main depois do termino da execução desse outro método... mas enfim, confesso que achei estranho não ter fechado estes cursores, mas nunca cheguei a ter problema com isso...

Saeger

Ja testei atribuindo null a eles e não houve resultados positivos.

É um problema aparentemente comum de acordo com o tópico de 2008 citado por mim… E o mais interessante é que não há uma solução na thread e se você pesquisar por este problema no forum da Oracle, você não encontra nada a respeito.
Pra mim é um know issue com o driver JDBC deles desde sempre… o.O

Criado 10 de maio de 2012
Ultima resposta 10 de mai. de 2012
Respostas 2
Participantes 2