Подтвердить что ты не робот

Должен ли я перехватывать исключения, возникающие при закрытии java.sql.Connection

Connection.close() может бросать SqlException, но я всегда предполагал, что можно игнорировать любые такие исключения (и я никогда не видел код, который их не игнорирует).

Обычно я писал бы:

 try{
    connection.close();
 }catch(Exception e) {}

Или

 try{
    connection.close();
 }catch(Exception e) {
     logger.log(e.getMessage(), e); 
 }

Возникает вопрос:

  • Это плохая практика (и у кого-то были проблемы при игнорировании таких исключений).
  • Когда Connection.close() делает какое-либо исключение.
  • Если плохо, как я должен обрабатывать исключение.

Комментарий:

Я знаю, что отбрасывание исключений является злым, но я говорю только об исключениях, которые были брошены при закрытии соединения (и, как я видел, это довольно распространено в этом случае).

Кто-нибудь знает, когда Connection.close() может что-то бросить?

4b9b3361

Ответ 1

Собственно, то, что вы делаете, это (почти) лучшая практика:-) вот что я увидел в Spring JdbcUtils.java. Таким образом, вы можете добавить другой блок Catch.

/**
 * Close the given  ResultSet and ignore any thrown exception.
 * This is useful for typical finally blocks in manual  code.
 * @param resultSet the  ResultSet to close
 * @see javax.resource.cci.ResultSet#close()
 */
private void closeResultSet(ResultSet resultSet) {
  if (resultSet != null) {
    try {
      resultSet.close();
    }
    catch (SQLException ex) {
      logger.debug("Could not close  ResultSet", ex);
    }
    catch (Throwable ex) {
      // We don't trust the  driver: It might throw RuntimeException or Error.
      logger.debug("Unexpected exception on closing  ResultSet", ex);
    }
  }
}

Ответ 2

В общем, у меня были дни, потраченные людьми, выбрасывающими подобные исключения.

Я рекомендую следовать нескольким основным правилам с исключениями:

Если вы БЕСПЛАТНО УВЕРЕНЫ, вы НИКОГДА не будете вызывать проблему с проверенным исключением, поймайте это исключение и просто укажите, почему вам не нужно его обрабатывать. (Sleep выбрасывает InterruptedException, которое всегда можно игнорировать, если вы на самом деле его не интересуете, но, честно говоря, это единственный случай, который я обычно игнорирую - даже если вы никогда не получите его, какова стоимость его регистрации?)

Если вы не уверены, но вы можете получить его изредка, поймайте и зарегистрируйте трассировку стека только так, чтобы, если это вызывает проблему, ее можно найти. Опять же, поймайте только то исключение, которое вам нужно.

Если вы не видите, как может быть выбрано исключенное исключение, поймайте его и повторно бросите его как исключенное исключение.

Если вы точно знаете, что вызывает исключение, поймите его и зарегистрируйте, почему именно вам не нужна трассировка стека в этом случае, если вы очень четко знаете, что вызывает его (и вы можете упомянуть класс, который если вы еще не используете log4j или что-то в этом роде.

Похоже, ваша проблема попадет в последнюю категорию, и для такого рода улов никогда не делайте то, что вы написали (исключение e), всегда делайте конкретное исключение только в том случае, если вызывается какое-то непроверенное исключение (плохие параметры, нулевой указатель,...)

Обновление: Основная проблема здесь заключается в том, что проверенные исключения некачественны. Единственный язык, в котором они существуют, - это Java. Они теоретичны, но в действии они вызывают такое поведение уловки и скрыть, что вы не получаете с непроверенными исключениями.

Многие люди прокомментировали тот факт, что я сказал, что скрыть их иногда бывает хорошо. Чтобы быть конкретным, в одном случае я могу подумать:

try {
    Thread.sleep(1000);
catch (InterruptedException e) {
    // I really don't care if this sleep is interrupted!
}

Я полагаю, что основная причина, по которой я считаю, что это использование в порядке, заключается в том, что это использование InterruptedException является злоупотреблением проверенным шаблоном исключения, в первую очередь, он сообщает результат сна больше, чем указывает условие исключения.

Было бы гораздо разумнее иметь:

boolean interrupted=Thread.sleep(1000);

Но они очень гордились своим новым шаблоном контрольных исключений, когда они впервые создали Java (понятно, что это действительно опрятно в концепции) только на практике)

Я не могу представить другого случая, когда это приемлемо, поэтому, возможно, я должен был бы указать это как , где он может быть прав, чтобы игнорировать исключение.

Ответ 3

Как минимум, всегда всегда всегда регистрировать исключения, которые вы ловите и не действуете.

Неприятно пойманы исключения, которые проглатываются без малейшего заглядания.

Ответ 4

Мне лично нравится ваша вторая идея по крайней мере регистрации ошибки. Поскольку вы ловите Exception, теоретически возможно поймать что-то, кроме SQL Exception. Я не уверен, что может произойти или как редко (например, исключения из памяти и т.д.), Но подавление всех ошибок не кажется мне правильным.

Если вы хотите подавить ошибки, я бы сделал это только для очень специфических, которые, как вы знаете, должны быть обработаны таким образом.

Гипотетическая ситуация: что, если ваш sql имел открытую транзакцию и закрытие соединения вызвало исключение из-за этого, хотите ли вы подавить эту ошибку? Даже подавление SQLExceptions может быть немного опасным.

Ответ 5

Вам нужно обработать исключение. Это не плохая практика. Представьте, что вы потеряли сеть перед закрытием соединения dabatase. Вероятно, это исключение.

Это редкость? Да. Я полагаю, что они называются исключениями, и это не повод игнорировать его. Помните, что если он может выйти из строя, он потерпит неудачу.

Вы также должны подумать о том, возможно ли иметь нулевое соединение в этот момент (это вызовет исключение NullPointerException) или нет.

if (connection != null) {
   try { 
      connection.close(); 
   } catch (SQLException sqle) { 
      logger.log(e.getMessage(), e); 
   }
}

Ответ 6

В идеальном мире вы никогда не должны ничего делать за исключением, конечно, в идеальном мире, вы никогда не получите исключение либо 8 -)

Итак, вам нужно изучить влияние различных параметров.

Только журнал: все операции с базой данных завершены, ничего не оставалось делать, кроме как очистить ресурсы. Если в этот момент возникает исключение, это, скорее всего, не влияет на выполненную работу, поэтому достаточно регистрировать ошибку. Конечно, если во время ведения журнала возникает ошибка, вам в основном приходится обрабатывать неудачную операцию базы данных, которая на самом деле не сработала.

Пустой обработчик: все операции с базой данных завершены, ничего не остается делать, кроме как очистить ресурсы. Если в этот момент возникает исключение, это, скорее всего, не влияет на выполненную работу, поэтому метод возвращается успешно. Следующий доступ к базе данных может работать в одной и той же проблеме, но это должно произойти в начале транзакции, где она будет корректно завершаться, а затем обрабатываться соответствующим образом. Если проблема исправлена, тогда не будет никаких указаний на то, что что-то пошло не так.

Это довольно типичный сценарий, чтобы поместить операцию закрытия() в блок finally, чтобы убедиться, что происходит очистка, поскольку мы не хотим, чтобы другие сбои препятствовали очистке ресурсов. Если ошибка не была выполнена, то ваш метод не должен терпеть неудачу, когда его операция будет успешно завершена. В этом случае пустая обработка исключений вполне нормальная.

Конечно, мнения будут отличаться.

Ответ 7

Вы также можете создать исключение RuntimeException:

try {
    connection.close();
 } catch(Exception e) {
     throw new RuntimeException(e); 
 }

Вам не придется менять свою подпись метода и позже сможет использовать метод Exception.getCause, чтобы найти причину проблемы.

Ответ 8

Обратите внимание, что Apache Commons DButils предоставляет метод closeQuietly(), который вы можете использовать, чтобы избежать загромождения кода с помощью "лишних" уловов. Примечание. Я не сторонник глотания исключений, но для этого сценария close() я считаю это общеприемлемым.

Ответ 9

По моему опыту игнорирование исключения никогда не является хорошей идеей. Поверьте мне, инженеры по технической поддержке и аналитики благодарят вас за тонну, если вы зарегистрировали исключение.

Кроме того, если вы используете правильную структуру ведения журнала, это будет отрицательное или минимальное влияние исключения.

Ответ 10

Если это ошибка, которая никогда не случается, я просто перекрою исключение и надеюсь, что никто ее не поймает.
если это любой другой случай, я, вероятно, зарегистрирую его

Ответ 11

Если вы можете справиться с этим, сделайте это (и запишите его, если это было неожиданно). Если вы не можете справиться с этим, то переверните его правильно, чтобы какой-то вышеописанный код мог его обработать.

Бесшумные глотательные исключения оставляют критическую информацию для человека, чтобы исправить код.

Ответ 12

Это лучшая практика для обработки исключения во время закрытия соединения с базой данных. Потому что, в какой-то момент времени в вашем коде, если вы пытаетесь получить доступ к объектам утверждения или результатов, то он автоматически вызывает исключение. Итак, лучше обработать исключение.