PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Postgres-Ausnahmen und java

SQLExceptoin abfangen Verwenden Sie dann SQLException.getSQLState() und vergleichen Sie es, um zu sehen, ob es das ist, was Sie wollen.

catch (SQLException ex) {
   final String ss = ex.getSQLState();
   //... blah blah ...
}

Siehe PostgreSQL-Fehlercodes für SQLState-Details. (Während die meisten Zustandskategorien und -codes in DBs Standard sind, implementieren sie nicht alle DBs auf die gleiche Weise und werfen sie zur gleichen Zeit, und die meisten DBs haben Extras, die DB-spezifisch sind).

Es gibt keine Möglichkeit, eine Ausnahme basierend auf dem SQLState abzufangen. Sie müssen es leider fangen, und wenn es nicht das ist, was Sie wollen, wickeln Sie es ein und werfen Sie es erneut. (Nicht einfach ohne Verpackung neu werfen, Sie verlieren den ursprünglichen Stapel).

In JDBC 4 gibt es Unterklassen von SQLException wie SQLNonTransientException die Sie abfangen können, aber nur, wenn der JDBC-Treiber diese Unterklassen auslöst. Zum Zeitpunkt des Schreibens unterstützt PgJDBC diese nicht und wirft immer einfach SQLException , also wenn du versuchst, sie zu fangen, wirst du nie etwas fangen. (Patches sind willkommen!).

In der realen Welt sind Sie normalerweise an einer Reihe verschiedener Fehlerbedingungen interessiert und möchten auf deren Grundlage verschiedene Dinge tun.

So etwas wie das ungetestete, ins Fenster geschriebene:

} catch (SQLException ex) {
  final String ss = ex.getSQLState();
  if (ss.equals("40001") || ss.equals("40P01")) {      
     /* It is a serialization failure or a deadlock abort. Retry the tx. */
     retry_transaction = true;
  } else if (ss.startsWith("08") || ss.startsWith("53")) {
     /* It is a connection error or resource limit. Reconnect and retry. */
     try {
        conn.close();
     } catch (SQLException ex) { 
        logger.log("Error closing suspected bad connection after SQLState " + ss, ex);
     }
     conn = null; /* App knows to reconnect if it sees a null connection */
     retry_transaction = true;
  } else {
     throw new MyAppException(ex);
  }
}

... wo Ihre App weiß, dass sie sich wieder verbinden muss, wenn sie eine Null-Verbindung sieht, und Aufzeichnungen über die gerade versuchte Transaktion führt, damit sie sie in einer Schleife wiederholen kann, bis sie erfolgreich ist, wenn sie auf einen Deadlock oder einen Serialisierungsfehler stößt.

In Wirklichkeit wären Sie klüger als dies, indem Sie eine Ratenbegrenzung für Wiederholungen usw. hinzufügen. Dies ist nur ein vereinfachtes Beispiel.

Um weitere Einzelheiten zu erfahren, wandeln Sie die Ausnahme in PSQLException nach dem Testen auf Gießbarkeit, oder fangen Sie es als PSQLException ab an erster Stelle. Dann Details abrufen mit:

ex.getServerErrorMessage()

was Ihnen eine ServerErrorMessage gibt mit detaillierten Feldern.