sql >> Base de Datos >  >> RDS >> PostgreSQL

Excepciones de Postgres y Java

Captura SQLExceptoin luego use SQLException.getSQLState() y compáralo para ver si es lo que quieres.

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

Ver Códigos de error de PostgreSQL para obtener detalles de SQLState. (Si bien la mayoría de las categorías y códigos de estado son estándar en las bases de datos, no todas las bases de datos las implementan de la misma manera y las lanzan al mismo tiempo, y la mayoría de las bases de datos tienen extras que son específicos de la base de datos).

No hay forma de detectar una excepción basada en SQLState. Desafortunadamente, debes atraparlo y, si no es lo que quieres, envuélvelo y tíralo de nuevo. (No vuelva a tirar sin envolver, perderá la pila original).

En JDBC 4 hay subclases de SQLException como SQLNonTransientException que puede capturar, pero solo si el controlador JDBC arroja esas subclases. Al momento de escribir, PgJDBC no los admite, y siempre simplemente arroja SQLException , así que si intentas atraparlos, nunca atraparás nada. (¡Los parches son bienvenidos!).

En el mundo real, por lo general, le interesan varias condiciones de error diferentes y quiere hacer cosas diferentes en función de ellas.

Algo vagamente como el no probado, escrito en la ventana:

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

... donde su aplicación sabe volver a conectarse si ve una conexión nula, y mantiene un registro de la transacción que acaba de intentar para que pueda volver a intentarlo en un bucle hasta que tenga éxito si llega a un punto muerto o una falla de serialización.

En realidad, sería más inteligente que esto, agregando una limitación de la tasa de reintentos, etc. Este es solo un ejemplo simplista.

Para obtener más detalles, envíe la excepción a PSQLException después de probar la castabilidad, o capturarlo como una PSQLException en primer lugar. Entonces obtenga detalles con:

ex.getServerErrorMessage()

que le da un ServerErrorMessage con campos detallados.