# richtiges Aufbauen/Schliessen der Verbindung



## Schreihalz (4. Nov 2005)

Hallo allerseits.. ich suche gerade nach einem Muster, wie man mit Objekten der Klassen 
Connection, ResultSet, Statement, ... umgeht. 

Die Aufgaben: Verb. Aufbauen -> Statements ausfüren -> alles Schliessen sollten sich in einem try/catch-Block befinden.

Zur Zeit bin ich bei folgendem Muster:


```
Connection conn = null;
      ResultSet rs = null;
      Statement st = null;

      try {
         Class.forName("z.B. -> com.mysql.jdbc.Driver");
         conn = DriverManager.getConnection("irgendein Connection-String");

         st = conn.createStatement();
         rs = st.executeQuery("irgendein select-Statement");

         /**
          * ... Bearbeitung der Sachen ...
          */

      } catch (Throwable e) {
         e.printStackTrace();
      } finally {
         try {
            if (rs != null) {
               rs.close();
            }
            if (st != null) {
               st.close();
            }
            if (conn != null) {
               conn.close();
            }
         } catch (SQLException sqle) {
            sqle.printStackTrace();
         }
      }
```

wichtig ist mir die Korrektheit bzw. Sicherheit, dass nach dem Ende des finally-Blocks, egal welche Fehler aufgetretten sind, auf jeden Fall keine Verbindungen oder Cursors die Datenbank belasten. 

wie macht ihr das? Kann jemand mein Muster beurteilen und evtl korrigieren?
wäre dankbar für jede Antwort.


----------



## Bleiglanz (4. Nov 2005)

nicht ganz korrekt:

wenn im finally der erste scheitert (rs.close), dann kommt er nicht mehr zum conn.close()

=> du musst dort jeden einzeln in ein try-catch packen

und: ein Throwable abfangen ist nur in absoluten Ausnahmefällen erlaubt!

```
Connection conn = null;
      ResultSet rs = null;
      Statement st = null;

      try {
         Class.forName("z.B. -> com.mysql.jdbc.Driver");
         conn = DriverManager.getConnection("irgendein Connection-String");

         st = conn.createStatement();
         rs = st.executeQuery("irgendein select-Statement");

         /**
          * weil im finally alle Ex verschluckt werden, mach
          * ichs hier auch schon, damit ich den Fehler
          * protokollieren kann
          */
         rs.close();
         rs=null;
         st.close();
         st=null;
         conn.close();
         conn=null;
      } catch (SQLException e) {
         e.printStackTrace(); // was soll man hier machen?
      } finally {
            if (rs != null) {
               try{rs.close();}catch(Exception e){}
            }
            if (st != null) {
               try{st.close();}catch(Exception e){}
            }
            if (conn != null) {
               try{conn.close();}catch(Exception e){}
            }
      }
```


----------



## Craven (4. Nov 2005)

Sobald Du die Verbindung zur Datenbank beendest sind auch alle Cursor, Temp-Segmente oder Statements, die nicht mit commit abgeschlossen wurden verfallen, d. h. werden im Arbeitsspeicher der Datenbank gelöscht. Darum brauchst Du dich eigentlich nicht kümmern, das macht die DB-Engine von selber! 

Es genügt, am Schluß deiner DB Aktionen 

conn.close(); 

aufzurufen!

Und immer dran denken: Laß die DB-Connection solange offen, wie Dein Programm läuft! Denn der Verbindungsaufbau braucht bei vielen SQL-Statements die größte Zeit. Also immer hübsch wiederverwenden!


----------



## Schreihalz (4. Nov 2005)

danke für die schnellen Antworten.

Es ist mir schon klar, dass man mit Connections "sparsam" umgehen sollte. Ich wollte eben ein komplettes Beispiel haben, da gehören Connections dazu 

Die Korrekturen sind einleuchtend. Nach der Version von Bleiglanz muss ich langsam mein Autoformat in Eclipse etwas anpassen, sonst habe ich 60 Zeilen Code, der eigentlich nichts tut


----------



## hanso80 (10. Nov 2005)

d.h. es ist nicht so wichtig, das resultset und das statement einzeln zu schliessen?


----------

