Frage

Ich habe Situation, wo ein 3rd-Party-Open-Source-Produkt Ich benutze läuft aus Cursor in Oracle und Empfangen der Fehler: java.sql.SQLException: ORA-01000: maximal geöffneten Cursor überschritten

Meine maximale Cursor wird auf 1000 gesetzt, und ich versuche, herauszufinden, ob der Code, der diese Grenze erreicht ist, etwas falsch zu tun, oder wenn ich einfach meine Grenze erhöhen muß.

Nach einigen Untersuchungen fand ich eine Stelle im Code, an dem ein ResultSet erstellt wird, um dadurch um 1 meine offene Cursor Zahl zu erhöhen jedoch, dass ResultSet bald nach Gebrauch geschlossen ist .... aber die Cursor Zahl bleibt, wo es ist . Ich war in der Lage, die Logik in einer einfachen JDBC-Anwendung außerhalb des 3rd-Party-Open-Source-Projektes zu reproduzieren.

package gov.nyc.doitt.cursor;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class CursorTest {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@myhost:1537:mydb", "username", "password");

            // as expected: there are 0 cursors associated with my session at this point

            ps = conn.prepareStatement("select my_column from my_table where my_id = ?");
            ps.setInt(1, 86);

            // as expected: there are 0 cursors associated with my session at this point

            rs = ps.executeQuery(); // opens 1 cursor

            // as expected: there is 1 open cursor associated with my session at this point
        } catch (Throwable t) {
            t.printStackTrace();
        } finally {
            // as expected: there is 1 open cursor associated with my session at this point
            try {
                rs.close();
            } catch (SQLException e) {
                System.err.println("Unable to close rs");
            }
            // not expected: there is still 1 open cursor associated with my session at this point
            try {
                ps.close();
            } catch (SQLException e) {
                System.err.println("Unable to close simplePs");
            }
            // not expected: there is still 1 open cursor associated with my session at this point
            try {
                conn.close();
            } catch (SQLException e) {
                System.err.println("Unable to close conn");
            }
            // as expected: at this point my session is dead and so are all the associated cursors
        }
    }
}

Ich fand einig Oracle-Dokumentation, die ich denke, dass alle offenen Cursor geschlossen werden würden, wenn Sie unsere ResultSet und PreparedStatements geschlossen, aber meine offene Cursor scheinen um zu hängen. Sehen Sie diese FAQ ( http: // Download bereit. oracle.com/docs/cd/B10501_01/java.920/a96654/basic.htm#1006509 ), die „Schließen einer Ergebnismenge oder Anweisung gibt den entsprechenden Cursor in der Datenbank.“, sagt Nur auf der Grundlage meiner Prüfung, die nicht zu passieren scheint, so muß ich ein grundlegendes Verständnis fehlen.

Kann mir jemand erklären, wie Oracle Griffe Cursor oder mir Punkt zu einem gewissen Dokumentation, die mich aufklären?

Danke!

War es hilfreich?

Lösung

Ganz schon vor langer Zeit mir ein ähnliches Problem begegnet ist. Soweit ich mich erinnere, war das Problem einer verzögerten Garbage Collection. Datenbank-Cursor nicht schließen, bis Garbage Collector Funde und gibt das entsprechende Objekt. Wenn Aussagen häufig erstellt werden, können Sie in dieser Ausgabe führen. Versuchen Sie, Garbage Collector manuell von Zeit zu Zeit aufrufen:

Runtime r = Runtime.getRuntime();
r.gc();

nur diese Vermutung zu überprüfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top