Java/JDBC: лучший шаблон проектирования для закрытия соединения с базой данных при возникновении исключения

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

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

Рассматривая шаблон проектирования ниже, есть ли лучший способ убедиться, что соединение JDBC с базой данных будет выпущено в случае исключения? Например, должен ли я также помещать код if ( conn != null) conn.close(); INSIDE в блок 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;
}

Ответ 1

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

На этой строке conn не может быть null. Самый популярный шаблон, вплоть до 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-with-resource. Вышеприведенный код может измениться до гораздо более короткого

try (Connection conn  = createConnection()) {
    // use connection 
} catch {
    // handle exception
}
// close is not required to be called explicitly

Ответ 2

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

Блок finally всегда выполняется, когда блок try завершается. Это гарантирует, что блок finally будет выполнен, даже если произойдет непредвиденное исключение.

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

Ответ 3

java se 7 поддерживает функцию try-with-resources. который генерирует окончательно для вас. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

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

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

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