PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Postgres Eccezioni e java

Cattura SQLExceptoin quindi utilizzare SQLException.getSQLState() e confrontalo per vedere se è quello che vuoi.

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

Vedi Codici di errore PostgreSQL per i dettagli di SQLState. (Sebbene la maggior parte delle categorie e dei codici di stato siano standard nei DB, non tutti i DB li implementano allo stesso modo e li lanciano contemporaneamente, e la maggior parte dei DB ha degli extra che sono specifici del DB).

Non è possibile rilevare un'eccezione basata su SQLState. Devi, sfortunatamente, prenderlo e, se non è quello che vuoi, avvolgerlo e lanciarlo di nuovo. (Non limitarti a rilanciare senza avvolgere, perdi lo stack originale).

In JDBC 4 ci sono sottoclassi di SQLException come SQLNonTransientException che puoi catturare, ma solo se il driver JDBC genera quelle sottoclassi. Al momento della scrittura, PgJDBC non li supporta e genera sempre semplicemente SQLException , quindi se provi a catturarli non catturerai mai nulla. (Le patch sono benvenute!).

Nel mondo reale di solito sei interessato a una serie di diverse condizioni di errore e vuoi fare cose diverse in base ad esse.

Qualcosa di vagamente simile al non testato, scritto nella finestra:

} 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);
  }
}

... dove la tua app sa di riconnettersi se vede una connessione nulla e tiene un registro della transazione che ha appena tentato in modo che possa riprovare in un ciclo finché non riesce se incontra un deadlock o un errore di serializzazione.

In realtà saresti più intelligente di così, aggiungendo la limitazione della velocità dei tentativi, ecc. Questo è solo un esempio semplicistico.

Per maggiori dettagli, esegui il cast dell'eccezione in PSQLException dopo aver testato la castability, o catturarlo come PSQLException innanzitutto. Quindi ottieni i dettagli con:

ex.getServerErrorMessage()

che ti dà un ServerErrorMessage con campi dettagliati.