PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Exceptions Postgres et Java

Attraper SQLExceptoin puis utilisez SQLException.getSQLState() et comparez-le pour voir si c'est ce que vous voulez.

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

Voir Codes d'erreur PostgreSQL pour les détails SQLState. (Bien que la plupart des catégories et des codes d'état soient standard dans les bases de données, toutes les bases de données ne les implémentent pas de la même manière et ne les lancent pas en même temps, et la plupart des bases de données ont des extras spécifiques à la base de données).

Il n'y a aucun moyen d'attraper une exception basée sur SQLState. Vous devez, malheureusement, l'attraper, et si ce n'est pas ce que vous voulez, emballez-le et relancez-le. (Ne vous contentez pas de relancer sans envelopper, vous perdez la pile d'origine).

Dans JDBC 4, il existe des sous-classes de SQLException comme SQLNonTransientException que vous pouvez attraper, mais seulement si le pilote JDBC lève ces sous-classes. Au moment de la rédaction, PgJDBC ne les prend pas en charge et lance toujours simplement SQLException , donc si vous essayez de les attraper, vous n'attraperez jamais rien. (Les correctifs sont les bienvenus !).

Dans le monde réel, vous êtes généralement intéressé par un certain nombre de conditions d'erreur différentes et souhaitez faire différentes choses en fonction de celles-ci.

Quelque chose qui ressemble vaguement au non testé, écrit dans la fenêtre :

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

... où votre application sait se reconnecter si elle voit une connexion nulle et conserve un enregistrement de la transaction qu'elle vient de tenter afin qu'elle puisse la réessayer dans une boucle jusqu'à ce qu'elle réussisse si elle rencontre un blocage ou un échec de sérialisation.

En réalité, vous seriez plus intelligent que cela, en ajoutant une limitation du taux de tentatives, etc. Ceci n'est qu'un exemple simpliste.

Pour plus de détails, convertissez l'exception en PSQLException après avoir testé la castabilité, ou l'attraper comme une PSQLException en premier lieu. Obtenez ensuite des détails avec :

ex.getServerErrorMessage()

qui vous donne un ServerErrorMessage avec des champs détaillés.