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.