2016-07-23 9 views
1

Ich habe festgestellt, dass ich in letzter Zeit keinen Zugriff auf meine PostgreSQL bekommen konnte. Alle 20 meiner erlaubten Verbindungen waren aufgebraucht. Ich konnte nicht verstehen warum, denn ich hatte nichts geöffnet. Scheint, dass Dinge offen bleiben, selbst nachdem der PC heruntergefahren wurde oder so. Ich benutze entfernte reale Datenbank, die lokal arbeitet und auch wenn ich live drücke, benutze dieselbe Datenbank.PostgreSQL Verbindung beenden, nachdem die Methode beendet ist

ist hier ein beispielhaftes Verfahren, das ich mich gefragt, ob Bedarf nach

@RequestMapping("/users") 
public String users(Model model) { 
    try { 
     Connection connection = getConnection(); 
     Statement stmt = connection.createStatement(); 
     String sql; 
     sql = "SELECT id, first, last, email, company, city FROM cuser"; 
     ResultSet rs = stmt.executeQuery(sql); 
     StringBuffer sb = new StringBuffer(); 
     List users = new ArrayList<>(); 
     while (rs.next()) { 
      int id = rs.getInt("id"); 
      String first = rs.getString("first"); 
      String last = rs.getString("last"); 
      String email = rs.getString("email"); 
      String company = rs.getString("company"); 
      String city = rs.getString("city"); 
      users.add(new User(id,first, last, email, company, city)); 
     } 
     model.addAttribute("users", users); 
     return "user"; 
    }catch(Exception e) {return e.toString();} 
} 

verwendet Schließ Wie soll ich Verbindungen am Ende dieses Verfahrens

Vielen Dank jeder, der

Antwort Zeit schließen wird
+2

Sie sollten einen Verbindungspool verwenden, und wenn Sie Spring Boot verwenden, kann etwas wie JdbcTemplate oder JPA Ihr Leben viel einfacher machen. – chrylis

+0

Ja mit Spring Boot, JDBC & PostgreSQL –

Antwort

1

Ok, hier gibt es einige Probleme.

Erstens ist, dass Datenbankverbindungen wirklich irgendwann auslaufen müssen. Manchmal wird die Zeitüberschreitung wegen eines Berichts, der ewig dauert oder eines ähnlichen Problems, auf etwas lächerliches ausgedehnt, aber es ist ein Antipattern. Sie benötigen die Verbindungen zu Zeitüberschreitung, damit die Datenbank bei einem Fehler wie einer unterbrochenen Verbindung wiederherstellen kann.

Zweitens, schließen Sie immer die Verbindung, wenn Sie damit fertig sind. Hier ist der einfachste Weg, try-with-resources zu verwenden, die sicherstellen, dass Ihre Ressourcen in der richtigen Reihenfolge geschlossen werden, ohne dass eine Ausnahmemaske möglich ist (wenn eine Ausnahme durch einen close ausgelöst wird, wird eine vorherige Ausnahme im try-Block ausgelöst) verloren zu gehen, was schlecht ist, weil es bedeutet, wissen Sie nicht, warum Ihr Code) fehlgeschlagen: mit mehr Frühling im Frühling Boot-Anwendung

try (Connection connection = getConnection(); 
    Statement stmt = connection.createStatement(); 
    ResultSet rs = stmt.executeQuery(sql)) { 
    StringBuffer sb = new StringBuffer(); 
    List users = new ArrayList<>(); 
    while (rs.next()) { 
     int id = rs.getInt("id"); 
     String first = rs.getString("first"); 
     String last = rs.getString("last"); 
     String email = rs.getString("email"); 
     String company = rs.getString("company"); 
     String city = rs.getString("city"); 
     users.add(new User(id,first, last, email, company, city)); 
    } 
    model.addAttribute("users", users); 
    return "user"; 
} 

Drittens betrachten. Sie haben einen Datenzugriff auf Ihren Controller, so dass Sie keine Bedenken haben, und Sie nutzen keine von Spring bereitgestellten Funktionen wie JDBC-Vorlagen mit Ressourcenabschluss, benannten Parametern, Datenausnahmeübersetzung (damit Ausnahmen) Sie erhalten von jdbc Aufrufe sinnvoll), oder Transaktionsabwicklung (damit Sie mehrere DAO-Aufrufe in der gleichen Transaktion machen können). Siehe this link für die Dokumentation zu spring-jdbc.

Stellen Sie sicher, dass Sie übrigens einen Verbindungspool verwenden; Es ist viel schneller, wenn eine Anforderung eine vorhandene Verbindung aus einem Pool verwendet, als wenn eine neue Verbindung hergestellt wird. Wenn Sie eine Verbindung aus dem Pool erhalten, wird sie in ein Objekt eingebettet, das die Verbindung zum Pool zurückgibt und die Bereinigung (wie das Zurücksetzen einer laufenden Transaktion) durchführt, wenn Sie auf close darauf zugreifen.

+0

Ok, ich werde deine Antwort ein paar Mal durchlesen müssen, um es zu verstehen. Hört sich gut an. Ich werde das alles implementieren, wie Sie es erklärt haben. Vielen Dank, dass Sie sich die Zeit genommen haben, mir zu helfen. Es ist gut erhalten –

0

Wie wäre es damit? (Dies setzt voraus, dass Sie JDBC direkt zum Öffnen Ihrer eigenen Verbindungen verwenden) ...

Connection conn = null; 
ResultSet rs = null; 
try { 
    conn = getConnection(); 
    ... 
} catch (Exception ex) { 
    ... 
} finally { 
    if (rs != null) { 
     try { rs.close(); } catch (Exception ex) { ... } 
    } 
    if (conn != null) { 
     try { conn.close(); } catch (Exception ex) { ... } 
    } 
} 
+0

@NathanHughes, Sie haben absolut Recht ... Ich lasse nur die Ausnahme behandeln am 'endlich'-Block für das Beispiel einfacher machen ... Ich werde es bearbeiten. Vielen Dank! –

Verwandte Themen