2008-10-29 2 views
12

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

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

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

Или

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

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

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

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

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

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

+0

Я всегда просто игнорировал их, видя, как я обычно делаю это с базой данных на этом этапе. – Powerlord 2008-10-29 19:45:32

+0

Пустые блоки блокировки являются злыми. Как достойный стрельбы. И, стреляя, я имею в виду гореть на костре. Даже простого оператора журнала было бы достаточно, люди! – erickson 2008-10-29 19:55:08

+1

Те, у кого есть пустые заявления на уловки «добровольцы», автоматически входят в список, чтобы позвонить, когда возникают проблемы с производством в 3 часа ночи. – 2010-04-04 09:55:26

ответ

10

На самом деле, то, что вы делаете, является (практически) лучшей практикой :-) Вот что я увидел в JdbcUtils.java в Spring. Таким образом, вы можете добавить еще один блок 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); 
    } 
    } 
} 
12

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

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

Если вы абсолютно уверены, что вы никогда не будет вызывать проблемы с проверяемого исключения, поймать именно это исключение и комментарии, почему именно вам не нужно, чтобы справиться с этим , (Sleep выбрасывает InterruptedException, которое всегда можно игнорировать, если вы на самом деле его не интересуете, но, честно говоря, это единственный случай, который я обычно игнорирую - даже при этом, если вы его никогда не получите, какова стоимость его регистрации?)

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

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

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

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

Обновление: Основная проблема здесь в том, что Checked Exce ptions непродуктивны. Единственный язык, в котором они существуют, - это 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 (понятно, что это очень аккуратным в концепции - только не на практике)

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

+0

Это * никогда * хорошая идея игнорировать исключение, даже если вы прокомментируете почему. Для регистрации исключения есть минимальные накладные расходы, и это минимальный результат, который должен быть выполнен, пока вы «... АБСОЛЮТНО УВЕРЕНЫ, что НИКОГДА не будете вызывать проблемы ...», проблемы возникают позже, а не сейчас. – 2008-10-29 22:01:40

+0

Мой самый большой случай для этого - сон() Он выдает проверенное исключение, которое чаще всего никогда не может быть достигнуто, и если оно достигнуто, кому это нужно? Если бы я заботился (конечно), я бы справился с этим. Но все же, прокомментируйте это. – 2008-10-29 22:24:44

3

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

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

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

1

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

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

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

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

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

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

1

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

Таким образом, вы должны изучить воздействия различные варианты.

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

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

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

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

6

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

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

0

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

1

Вы также можете бросить RuntimeException:

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

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

1

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

0

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

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

0

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

Смежные вопросы