리팩토링 한답시고 2일 동안 배운 기술은 다음과 같다.
가장 큰 건 main과 DAO, DTO의 분리이다. 이로 인해 파트별로 분업이 가능해졌다.
그러나, 남은 한 가지 문제는 연결이다.
우리가 만든 프로그램은 DB, UI가 한 컴퓨터에 존재한다. 한 마디로 싱글 플레이이다.
하지만 실 서비스는 여러 고객이 네트워크를 타고 본사의 DB를 통해 CRUD를 한다.
하나의 DB-하나의 사용자 | 하나의 DB-여러 사용자
따라서 실 서비스에선 다음과 같은 문제가 있다.
동접자가 많을 경우, 연결을
try-resource
처리해도 그 이상의 접속이 들어오면서 DB가 오작동을 일으킬 수도 있다.
일단 try-resource
때문에 메서드 사용 후, 연결은 무조건 끊긴다.
하지만 기본 연결이 100인데, 그 이상이 동시에 들어오면 연결을 끊기 전에 한도를 초과하는 Connection
이 생성되게 된다.
이 경우, DB가 뻗는다.
DB – DBMS – (connection) - DBCP – DAO – UI
그 해결방안으로 나온 것이 ‘DBCP기법(DateBase Connection Pool)’ 이다.
DBCP 외장라이브러리를 검색해서 넣는다. 다만 ‘의존성 라이브러리’이기 때문에 잘 찾아서
불러오면 된다.
public Connection getConnection() throws Exception{
BasicDataSource bds = new BasicDataSource(); // DBCP Object
bds.setUsername("kh");
bds.setPassword("kh");
bds.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
bds.setDriverClassName("oracle.jdbc.driver.OracleDriver"); // 드라이버 로딩
bds.setInitialSize(30);
return bds.getConnection();
}
: DBCP인스턴스 문제
위와 같은 방식은 메서드를 실행할 때마다, 인스턴스를 생성한다.
그러면 메서드가 실행될 때마다 30개의 연결이 만들어진다.
물론 지역변수라 메서드가 끝나면 지워지는게 당연하지만 메모리 상에서 지워지는 타이밍이 생각보다 늦기 때문에, 첫 문제처럼 똑같은 일이 발생한다.
생성자와 멤버필드로 해서 DAO 인스턴스를 만들 때만 생성되게 한다.
물론, 프로그램을 만들면 하나의 DB에 연결된 여러 DAO가 존재한다.
따라서 이 방법도 어느 순간 앞의 문제가 DAO의 영역에서 발생한다. 하지만 이 부분은 현 시점에서 다루려면 복잡하기 때문에 Web 이후에 다루고자 한다.
private BasicDataSource bds = null; // 어느 메서드에서든지 사용할 수 있음
// 생성자
public CafeMenuDAO() {
this.bds = new BasicDataSource();
bds.setUsername("kh");
bds.setPassword("kh");
bds.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
bds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
bds.setInitialSize(30);
}
// getConnection
public Connection getConnection() throws Exception{
return bds.getConnection();
}