여기저기 블로깅 하면서 많이 듣고, 많이 보던 얘기인데, 좋은 방법을 하나 찾은거같다.

 DbUtils.closeQuietly() 이 메소드를 쓰니까 한방에 되네!

완전 굿인듯 ㅋㅋ 맨날 클로즈 메소드를 만든것도 귀찮았는데.. 




Java 리소스 닫기(Resource Close)를 제대로 하려면.. 프로그래밍

요즘 보고 있는 책 Core EJB 책을 보다보니 Stream 을 닫는 부분이 잘못 나와있다.
(뭐, 이거 빼고는 아직은 읽기에 부담스럽지 않고 만족스럽다..)

어찌 했냐면,


try {
...
} catch(..) {
...
} finally {
    if (writer != null) writer.close();
    if (reader != null) reader.close();
    if (socket != null) socket.close();
}


위와 같이 했는데, 이렇게 하면 안된다.

위와 같이하면 첫번째 writer.close() 에서 예외가 발생하면 그 이후의 다른 close() 문들은 전혀 실행되지 않고 빠져나가 버려 리소스 누수가 발생하게 된다.

이것은 스트림이나 소켓 뿐만 아니라 JDBC Connection 에서도 마찬가지 이다.

그러므로 다음과 같이 바꿔야만 쓰겠다.


try {
...
} catch(..) {
...
} finally {
    if (writer != null) {
        try { writer.close(); } catch (Exception ex) {}
    }

    if (reader != null) {
        try { reader.close(); } catch (Exception ex) {}
    }

    if (socket != null) {
        try { socket.close(); } catch (Exception ex) {}
    }
}


if / for / while 문 등은 비록 실행할 문장이 한 개 뿐이라도 괄호를 치는 것을 원칙으로 한다.
그리고 일일이 귀찮더라도 다 try/catch 안에 .close() 문을 넣어야 안전하게 리소스를 닫는 것이 된다.

Jakarta Commons DBUtils에는 저런 귀찮은 try/catch 없이 메소드 하나 호출로 JDBC 리소스를 닫아주는 메소드가 있다.
DbUtils.closeQuietly()를 한번 사용해 보시라.
 
 


출처 : http://kwon37xi.egloos.com/
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


Connection conn = null;
  PreparedStatement pstmt = null; // <-------- !!
  ResultSet rs = null;
  try {
    conn = ......;
    pstmt = conn.prepareStatement("select .... ?...?");
    pstmt.setString(1,"xxxx");
    pstmt.setString(2,"yyyy");
    rs = pstmt.executeQuery(); <--- 여기서 SQLException 이 일어나더라도...
    while(rs.next()){
      ....
    }
    //rs.close();
    //pstmt.close(); 
  }
  finally{
    if ( rs != null ) try {rs.close();}catch(Exception e){}
    if ( pstmt != null ) try {pstmt.close();}catch(Exception e){} // <-- !!!!
    if ( conn != null ) ......;
  }



=============================================================================================================
반복문을 이용할 때

Connection conn = null; PreparedStatement pstmt = null; try { conn = ......; pstmt = conn.prepareStatement("update .... ?... where id = ?"); for(int i=0;i<10;i++){ pstmt.clearParameters(); pstmt.setString(1,"xxxx"); pstmt.setString(2,"id"+(i+1) ); int affected = pstmt.executeUpdate(); if ( affected == 0 ) throw new Exception("NoAffected"); else if ( affedted > 1 ) throw new Exception("TooManyAffected"); } } finally{ if ( pstmt != null ) try {pstmt.close();}catch(Exception e){} if ( conn != null ) ......; }

PreparedStatement 라는 것이, 한번 파싱하여 동일한 SQL문장을 곧바로 Execution할 수
  있는 장점이 있는 것이고, 궁극적으로 위와 같은 경우에 효과를 극대화 할 수 있는
  것이지요.
-------------------------------------------------------  
  본 문서는 자유롭게 배포/복사 할 수 있으나 반드시
  이 문서의 저자에 대한 언급을 삭제하시면 안됩니다
================================================
  자바서비스넷 이원영
  E-mail: javaservice@hanmail.net
  PCS:010-6239-6498
================================================
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST