WAS/JBoss

[TroubleShooting] JBoss JDBC connection leak 해결방안

투칼론 2016. 8. 13. 08:56
반응형

1. JDBC Connection Leak 이란?


DB 접근을 위해 Connection Pool 자원을 사용하는데 이를 반납하지 않아, 사용가능한 Connection Pool이 지속적으로 줄어드는 현상을 말한다.



2. JDBC 프로그램 예제


......

DataSource ds = null;

Connection con = null;
Statement stmt = null;
ResultSet rs = null;

String query = "SELECT EMPNO, ENAME FROM EMP";


try {
    ctx = new InitialContext();
    ds = (DataSource)ctx.lookup("java:OracleDS");  

    con = ds.getConnection();

    stmt = con.createStatement();
    rs = stmt.executeQuery(query);


    while(rs.next()) {

    ......
    }

}catch(Exception exception){

}finally{

if(rs!= null) try { rs.close(); } catch(Exception ex){}
if(stmt!= null) try {stmt.close(); } catch(Exception ex){}
if(con!= null) try { con.close(); } catch(Exception ex){}

}



3. Leak 발생원인


JBoss에서 제공하는 JDBC Connection Pool을 이용하여 DB를 조작하는 프로그래밍(위 예시 참조)할 때, 보통 ResultSet, Statement, Connection을 생성하거나, 얻어서 코드를 작성 한다.

이때 사용한 ResultSet, Statement, Connection 자원에 대하여 반드시 close()를 통해 자원을 반납해야 하는데, 반납하지 않는 경우에 발생한다. 위의 예제 프로그램에서 붉은 글씨 부분을 처리하지 않았을 때 발생한다.


ResultSet과 Statement 객체를 여러 개 생성하였다면, 생성한 모든 자원에 대해 반납을 해야한다.



4. Connection Leak을 해결하기 위한 자동 복구 및 Profiling 방법


수많은 소스 코드를 모두 확인하는 방법도 있겠지만, 다행히도 JBoss에서는 쉽게 찾을 수 있도록 기능을 지원한다.


1) 데이터소스 서브시스템에서 Cached Connection Manager(CCM) 디버그 설정


    <subsystem xmlns="urn:jboss:domain:datasources:1.1">

       <datasources>

          <datasource ... enabled="true" use-ccm="true">

             ...

          </datasource>

       </datasources>

    </subsystem>



2) jca 서브시스템에서  <cached-connection-manager>에 debug 옵션 설정


       <subsystem xmlns="urn:jboss:domain:jca:1.1">

          ...

          <cached-connection-manager debug="true" error="false"/>

          ...

       </subsystem>


위의 옵션을 설정하면 아래와 같은 처리가 된다.

  • JBoss 로그 파일에 "Closing a connection for you. Please close them yourself" 출력됨

  • leak 된 connection이 처음 open된 코드의 stacktrace가 출력됨

  • leak 된 connection을 자동 close 함

추가로 아래와 같이 추가로 error="true" 설정하면, RuntimeError가 발생하고, 로그파일에 ERROR로 출력된다.
<cached-connection-manager debug="true" error="false" />


5. 해결 방안


위의 설명과 같이 JBoss가 자동 close시키지만, 근본적인 소스 오류를 찾아 수정해야 한다.


해당 소스는 JBoss 로그 파일에 출력된 stack trace를 보면, leak이 발생한 소스 위치를 쉽게 확인 할 수 있다.