Capturar
SQLExceptoin
então use SQLException.getSQLState()
e compará-lo para ver se é o que você quer. catch (SQLException ex) {
final String ss = ex.getSQLState();
//... blah blah ...
}
Consulte Códigos de erro do PostgreSQL para detalhes do SQLState. (Embora a maioria das categorias e códigos de estado sejam padrão nos bancos de dados, nem todos os bancos de dados os implementam da mesma maneira e os lançam ao mesmo tempo, e a maioria dos bancos de dados possui extras específicos do banco de dados).
Não há como capturar uma exceção com base no SQLState. Você deve, infelizmente, pegá-lo e, se não for o que deseja, embrulhe e jogue novamente. (Não basta jogar novamente sem embrulhar, você perde a pilha original).
No JDBC 4 existem subclasses de
SQLException
como SQLNonTransientException
que você pode capturar, mas somente se o driver JDBC lançar essas subclasses. No momento da escrita, o PgJDBC não suporta isso e sempre simplesmente lança SQLException
, então, se você tentar pegá-los, nunca pegará nada. (Remendos são bem-vindos!). No mundo real, você geralmente está interessado em várias condições de erro diferentes e deseja fazer coisas diferentes com base nelas.
Algo vagamente como o não testado, escrito na janela:
} 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);
}
}
... onde seu aplicativo sabe se reconectar se vir uma conexão nula e mantém um registro da transação que acabou de tentar para que possa tentar novamente em um loop até que seja bem-sucedido se atingir um impasse ou falha de serialização.
Na realidade, você seria mais esperto do que isso, adicionando limitação de taxa de tentativas, etc. Este é apenas um exemplo simplista.
Para obter mais detalhes, lance a exceção para
PSQLException
após o teste de castability, ou capturá-lo como um PSQLException
em primeiro lugar. Então obtenha detalhes com:ex.getServerErrorMessage()
que fornece uma
ServerErrorMessage
com campos detalhados.