Вопрос по database, java, oracle, jdbc – Java / JDBC: лучший шаблон проектирования для закрытия соединения с базой данных при возникновении исключения

7

Я новичок в Java (я использую Java 6). Я использовал приведенный ниже шаблон проектирования для всех моих Java POJO и сервлетов для доступа к базе данных Oracle 11G через веб-сервер GlassFish 3.1.2.

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

Глядя на шаблон проектирования ниже, есть ли лучший способ убедиться, что соединение JDBC с базой данных освобождается в случае исключения? Например, я должен также разместитьif ( conn != null) conn.close(); код ВНУТРИ блока catch? Или есть лучший дизайн шаблона? Заранее спасибо за любые комментарии / подсказки.

public String MyFunction() throws Exception {     

    Connection conn;
    CallableStatement cs;

  try {

      Context context = new InitialContext();
      DataSource ds = (DataSource)context.lookup("jdbc/MyPool");
      conn = ds.getConnection();        

      cs = conn.prepareCall( "{call my_sproc (?)}" );

      cs.registerOutParameter(1, Types.VARCHAR);

      cs.execute();

      String outParam = cs.getString(1); 

      if ( conn != null )  // close connection
         conn.close();

  } catch (Exception e) {
      outParam = "an error occurred";
  }
    return outparam;
}
Обратите внимание, что также может быть полезно закрыть наборы результатов и операторы. Вот полезная ссылка (см. Ответ Стефана Швайцера в ссылке для хорошего шаблона дизайна):stackoverflow.com/questions/103938/… ggkmath

Ваш Ответ

4   ответа
29
if ( conn != null )  // close connection
         conn.close();

На этой линииconn cannot быть нулевым Самый популярный шаблон вплоть до Java 6:

Connection conn = null;
try {
   // initialize connection
   // use connection 
} catch {
  // handle exception
} finally {
  if (conn != null) {
     try { conn.close(); } catch (Exception e) { /* handle close exception, quite usually ignore */ } 
     }
}

СJava 7 это станет менее громоздким с егопопробуйте-с ресурсом построить. Приведенный выше код может измениться на гораздо более короткий

try (Connection conn  = createConnection()) {
    // use connection 
} catch {
    // handle exception
}
// close is not required to be called explicitly
Хорошо, я, наверное, войду, спасибо! ggkmath
Да, как я показал в своем шаблоне, соединения, как правило, закрываются только в окончании.
Просто чтобы быть понятным, поскольку, наконец, выполняется независимо от того, что, мне не нужно закрывать соединение внутри блока try, верно? Я могу просто закрыть соединение один раз в коде, который находится в блоке finally. Это правильно? ggkmath
Да, исключения изconnection.close() часто игнорируются или по большей части регистрируются, но не обрабатываются каким-либо другим способом :) Я не знаю, почему; На самом деле я никогда не видел, чтобы близкие бросали исключение.
Спасибо, несчастная переменная, когда говоришь "до Java 6" Вы имеете в виду "вплоть до Java 6"? (это то, что я использую)? Я так полагаю. Кроме того, когда вы говорите «обычно игнорируется», вы ссылаетесь только наtry...catch в блоке finally (то естьif (conn != null) conn.close(); всегда там, верно?) Почему люди обычно игнорируют обработку исключения в блоке finally для закрытия соединения? ggkmath
2

Я предпочитаю другой более элегантный способ, чем:

} finally {
  if (conn != null) {
     try {
         conn.close();
     } catch (Exception e) {
         /* handle close exception, quite usually ignore */
     } 
  }
}

Вы можете использовать DbUtils.closeQuietly:http://commons.apache.org/dbutils/apidocs/org/apache/commons/dbutils/DbUtils.html

4

Использоватьfinally блокировать всегда, чтобы высвободить ресурсы.

The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs.

  try {

      Context context = new InitialContext();
      DataSource ds = (DataSource)context.lookup("jdbc/MyPool");
      conn = ds.getConnection();        

      cs = conn.prepareCall( "{call my_sproc (?)}" );

      cs.registerOutParameter(1, Types.VARCHAR);

      cs.execute();

      String outParam = cs.getString(1); 


  } catch (Exception e) {
      outParam = "an error occurred";
  }
 finally {
       conn.close();
    } 
Если вы подозреваете, чтоconn.close() снова выдаст ошибку, окружите ееtry catch finally также.
@ggkmath да, вам нужно проверитьconn != null; может быть нулевым, еслиds.getConnection() выбрасывает исключение. И будь вы подозреваете или нет, вам нужно поставитьclose() вtry/catch/finally; иначе метод должен включить его в свойthrows пункт, который не хорошо.
Спасибо Казекаге, Уиллconn.close() строка кода в блоке finally выдает ошибку, если соединение еще не открыто или по какой-либо другой причине? Если да, то я не должен использовать этоif (conn!=null) утверждение выше в блоке finally? ggkmath
2

Java 7 поддерживает функцию пробного использования ресурсов. это создает окончательно для вас.http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Блок finally закроет ресурсы, выделенные в попытке. как вы использовали ключевое слово, используя в C #

Однако пользователь использует Java SE6 ... Смотрите параметры других пользователей :)

ВАЖНО: Используемые заявления также должны быть закрыты.

Я был неправ. Апидоки дляConnection не говорите, что закрытиеConnection закрывает егоStatements; но обратите внимание, что закрытиеStatement is требуется закрытьResultSets
Я не читал, но пользователь Miserable Variable тоже говорил о попытке с ресурсами.
Отличный справочник для пользователей java se 7, спасибо! ggkmath

Похожие вопросы