본문 바로가기
개발/JAVA

(DBCP)Connection Pooling에 대해 알아보자

by pastry 2015. 1. 4.

기존 수업에서 java로 DB에 접속할때 JDBC(Java DataBase Connectivity)를 사용했는데

이번에 프로젝트로 웹사이트를 구축하다보니 문제가 생겼다.

JDBC는 매번 connection을 생성하고 close해줘야 하는데 connection을 생성할때 지연되는 시간이 좀 있다.

서비스를 제공받는 입장에서는 조금이라도 느리면 답답하기 마련이므로 접속 속도는 무시할 수 없는 요소.

고로 해결방법을 찾아봤는데 DBCP이란게 있더라.

 

database connection pooling은 connection을 미리 생성해 놓고 접속을 요할때 할당해주고 다시 반납받는 방식으로 지연시간을 줄이는 방식이다.

 

내가 실습하는 환경은 tomcat 7.0인데 7.0이상부터는 라이브러리가 내장되있다고 한다.

따라서 설정만 몇개 해주면 사용할 수 있다.

 

*이하 코드는 DB: oracle 기준

 

자바에서 제공하는 connection pooling은 JNDI을 이용해서 사용해야 한다.

JNDI(Java Naming and Directory Interface)는 필요한 자원을 key/value로 mapping해서 나중에 key로 특정 자원을 사용할 수 있게 해주는 기술이다. 지금보니 servlet를 사용할때도 이런식으로 사용했었다. 강사님한테 질문을 좀 해보고 자세한 내용을 업데이트 예정.

 

1-1. tomcat server에 context.xml에 다음 코드를 추가한다.

 

<Resource

   name="jdbc/myoracle" auth="Container" type="javax.sql.DataSource"
   driverClassName="oracle.jdbc.OracleDriver" 
   url="jdbc:oracle:thin:@localhost:1521:xe"
   username="oraclejava" 
   password="oraclejava" 
   maxActive="20" 
   maxIdle="10" 
   maxWait="-1"

/>

 

각 속성에 대한 설명


 name : JNDI로 호출될 이름을 설정한다.
  (접근 -> java:comp/env/jdbc/myoracle)
 auth : DBCP를 관리할 관리자 (Container or Application)
 type : 해당 resource의 return type 
  (DataSource는 Connection 객체를 반환할 수 있다.)
 factory : dbcp를 유용하는 관리 클래스
  (Tomcat 5.x에 기본으로 존재하는 클래스)
  (직접 DBCP 클래스를 지정해도 동작하는데 문제가 없다.)
  (그러나, Factory 클래스를 이용하면 좀더 안정적으로 관리할 수 있다.)
 dirverClassName : JDBC를 이용하기 위한 드라이버 클래스
 url : DB의 접속 URL (속성으로 자동 재 접속을 선택했다.) 
 username : DB의 계정 명
 password : 계정에 대한 비밀번호
 maxActive : 최대 접속 허용 개수
 maxIdle : DB Pool에 여분으로 남겨질 최대 Connection 개수
 maxWait : DB 연결이 반환되는 Timeout의 최대 시간 (-1은 무한 대기)
 removeAbandoned : Connection이 잘못 관리되어 버려진 연결을 찾아 재활용할 것인지의 여부 설정
  (true 설정일 때 현재 DB 연결이 적으면 버려진 연결을 찾아 재활용)
 removeAbandonedTimeout : 버려진 연결로 인식할 기본 시간 설정
  (초 단위로 해당 시간이 지나면 버려진 연결로 인식한다.)

 

속성에 대한 더 자세한 설명은 여기 에서 확인하자.

 

1-2. context.xml을 복사한다.

방금 설정한 값은 server에 종속되므로, 서버가 바뀌거나 서버에서 프로젝트가 제거될때 다시 설정해줘야 한다.

svn으로 프로젝트를 진행하기 때문에 팀원들에게도 설정이 동일하게 적용되야 하므로 파일 위치를

WebContent/META-INF/context.xml 복사(혹은 이동)한다.

 

2.web.xml에서 mapping하기

mapping을 해줘야 하기 때문에 WebContent/WEB-INF에 web.xml을 생성(이미 존재한다면 코드 추가)해야한다.

mapping되는 이름은 context.xml에 있던 name 속성이다.

 

 <resource-ref>
     <description>Connection</description>
     <res-ref-name>jdbc/oracle</res-ref-name>
     <res-type>javax.sql.DataSource</res-type>
     <res-auth>Container</res-auth>
 </resource-ref>

 

 

3.JAVA 코드작성

 

MVC패턴을 이용해 작성할 예정으므로 DBUtil이란 이름으로 파일을 작성하고 내부에 아래 코드를 넣어주면 된다.

 

 public static Connection getConnection() {
  Connection conn = null;
  try {
   Context ctx = new InitialContext();
   DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/oracle");
   conn = ds.getConnection();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return conn;
 }

 

위 코드에서 Context는 naming 서비스를 이용하기 위해 바인딩 정보를 가지고 있는 context객체이다. 이 context 객체를 통해서 name으로 등록된 DBCP객체를 가져온다. 그리고 이 context객체를 이용해서 datasource타입으로 반환시킨다. JDBC에서 connection을 받을때는 DriverManager에서 받아왔었는데 여기서는 Datasource에서 받아오게 된다.


 

 connection 사용을 마쳤으면 close를 해주면 되는데 여기서 close는 JDBC때와 다르게 connection pool로 반납이 이루어진다.


작성을 하다보니 DataSource와 Context에 대한 API를 좀 찾아봐야 할것같은데..

주말이니까 오늘은 쉬고 다음에 좀 읽어보고 업데이트 해야겠다.

 

 

 

 

 

 

'개발 > JAVA' 카테고리의 다른 글

IoC구현 방법 - DI관리  (0) 2015.01.20
클레스의 결합관계: 객체 결합과 유지 보수성  (0) 2015.01.20
#writer에서 \n가 안먹힐때  (0) 2014.12.16
HashMap으로 보는 Iterator의 유용성  (2) 2014.11.26
GUI programming  (0) 2014.11.26

댓글