Vengo a menudo a través de situaciones como :-

try{ 
     ...
     stmts
     ...
} 
catch(Exception ex) {
     ... 
     stmts
     ... 
} finally {
     connection.close //throws an exception
}

que aún necesita un bloque try – catch en el interior finalmente.

¿Cuál es la mejor práctica para superar esto?

  • Usted probablemente encontrará que el recurso de adquisición de tiros también. (Así que en realidad el uso de seth respuesta.)
InformationsquelleAutor Ajay | 2009-08-26

10 Comentarios

  1. 26

    Escribir un SQLUtils clase que contiene static closeQuietly de que los métodos de captura y registro de tales excepciones, a continuación, utilizar, según corresponda.

    Usted va a terminar con algo que dice así:

    public class SQLUtils 
    {
      private static Log log = LogFactory.getLog(SQLUtils.class);
    
      public static void closeQuietly(Connection connection)
      {
        try
        {
          if (connection != null)
          {
            connection.close();
          }
        }
        catch (SQLExcetpion e)
        {
          log.error("An error occurred closing connection.", e);
        }
      }
    
      public static void closeQuietly(Statement statement)
      {
        try
        {
          if (statement!= null)
          {
            statement.close();
          }
        }
        catch (SQLExcetpion e)
        {
          log.error("An error occurred closing statement.", e);
        }
      }
    
      public static void closeQuietly(ResultSet resultSet)
      {
        try
        {
          if (resultSet!= null)
          {
            resultSet.close();
          }
        }
        catch (SQLExcetpion e)
        {
          log.error("An error occurred closing result set.", e);
        }
      }
    }

    Y su código de cliente será algo como:

    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try 
    {
      connection = getConnection();
      statement = connection.prepareStatement(...);
      resultSet = statement.executeQuery();
    
      ...
    }
    finally
    {
      SQLUtils.closeQuietly(resultSet);
      SQLUtils.closeQuietly(statment);
      SQLUtils.closeQuietly(connection);
    }

    Actualización: desde Java 7, los diversos JDBC interfaces de extender java.lang.AutoCloseable y mientras que el código anterior responde a la pregunta original, si usted está escribiendo el código directamente en contra de la API de JDBC, ahora puede ser estructurado:

    try (
      Connection connection = getConnection();
      PreparedStatement statement = connection.prepareStatement(...);
      ResultSet resultSet = statement.executeQuery()
    )
    {
      ...
    }
    • Esta es mi elección, así como en el pasado, pero no he encontrado en estos días que hay clases, como apache commons DBUtil, que hacer esto para usted.
    • parece una buena opción 🙂 Gracias
  2. 12

    Como otros han mencionado, una estática closeQuietly utilidad es el camino a seguir. Una cosa a añadir – si usted está en el mundo de la java.io en lugar de java.sql entonces hay una interfaz útil para este propósito – java.io.Closeable

    Todas las fuentes de datos y se hunde en java.io implementar esta interfaz – todos los arroyos, canales, escritores y lectores. De esa manera usted puede crear una utilidad para hacer frente a la misma «excepción en close()» problema sin necesidad de muchas versiones sobrecargadas.

    por ejemplo,

    public class IoUtils {
    
      public static closeQuietly (Closeable closeable) {
        try {
          closeable.close();
        } catch (IOException logAndContinue) {
          ...
        }
      }
    
    }
  3. 10

    Por lo general lo hizo de esta manera:

    try {
        try {
            ..
            stmts
            ...
        }
        finally {
           connection.close():
        }
    } catch (Exception ex) {
         ..
         stmts
         ..    
    }

    Por lo general sólo utiliza este cuando yo no estaba usando una biblioteca de la que se ocupó de este plomería para mí.

    Como Imagist señala, esto no es técnicamente el mismo que el que finalmente se ejecutará antes de la captura, pero creo que se soluciona el problema que se intenta resolver.

    • Que no es técnicamente lo mismo, pero dependiendo de la situación en la que se puede hacer lo que Ajay quiere.
    • Buen punto. Voy a actualizar mi respuesta. Gracias.
    • Usted puede, por supuesto, a continuación, resumen que con la Ejecución de Todo lenguaje.
    • gracias! No había visto eso antes. He aquí un enlace sobre los otros que están interesados: stackoverflow.com/questions/341971/…
    • El problema con este enfoque es que normalmente no desea hacer lo mismo con las excepciones relacionadas con la cerca que ver con excepciones en el cuerpo principal del método – y peor aún, este código se tragaría excepciones en el cuerpo principal si finalmente lanzó una excepción.
  4. 4

    Commons-io también ha closeQuietly() para la entrada y flujos de salida. Lo estoy usando todo el tiempo. Hace el código mucho más legible.

  5. 2

    En Java 10, se puede escribir:

    public void java10() throws SQLException {
        try (var connection = Connections.openConnection();
             var callableStatement = connection.prepareCall("my_call");
             var resultSet = callableStatement.executeQuery()) {
    
            while (resultSet.next()) {
                var value = resultSet.getString(1);
                System.out.println(value);
            }
        }
    }

    En Java 7, 8 y 9, se puede escribir:

    public void java7() throws SQLException {
        try (Connection connection = Connections.openConnection();
             CallableStatement callableStatement = connection.prepareCall("my_call");
             ResultSet resultSet = callableStatement.executeQuery()) {
    
            while (resultSet.next()) {
                String value = resultSet.getString(1);
                System.out.println(value);
            }
        }
    }

    En Java 6 usted necesita para escribir todas estas líneas:

    public void java6() throws SQLException {
        Connection connection = Connections.openConnection();
        try {
            CallableStatement callableStatement = connection.prepareCall("my_call");
            try {
                ResultSet resultSet = callableStatement.executeQuery();
                try {
                    while (resultSet.next()) {
                        String value = resultSet.getString(1);
                        System.out.println(value);
                    }
                } finally {
                    try {
                        resultSet.close();
                    } catch (Exception ignored) {
                    }
                }
            } finally {
                try {
                    callableStatement.close();
                } catch (Exception ignored) {
                }
            }
        } finally {
            try {
                connection.close();
            } catch (Exception ignored) {
            }
        }
    }
  6. 0

    General, usted no quiere hacer nada más que el registro de una excepción que sucede cuando el cierre de un recurso, por lo que realmente debe ir en su propio try/catch. Sin embargo, este es el código genérico que va a suceder a menudo, así que no se Repita a sí Mismo, y poner el cierre a un método estático (como Nick Holt sugiere) de esa manera usted no tendrá los dos try/catch elementos en el mismo método, haciendo que el código sea más fácil de leer y seguir.

    • No estoy seguro de que estoy de acuerdo con eso. En mi opinión, un fracaso en el cierre de un recurso representa un problema más grave que una típica excepción de que iba a ocurrir durante el uso. Uno debe esforzarse para mantener el interior de la excepción (más fácil en vb.net de C#), pero lanzar un «más grave» de uno.
    • Si usted está leyendo de la red y listo, es realmente de ninguna consecuencia, que el recurso no logró cerrar? Ciertamente no cambia nada sobre el programa.
    • a menos que se deja abierto el puerto y no se puede utilizar para cualquier otra persona
  7. 0

    También es útil Closeables#closeQuitely método en Google de la Guayaba de la biblioteca – que puede ser utilizado para cualquier Closeable

  8. -1

    sólo recuerde .. finalmente consigue siempre que se ejecute con try o catch ..

    • no llega a su punto

Dejar respuesta

Please enter your comment!
Please enter your name here