어플리케이션 서버와 DB간에 데이터를 주고 받는 순서는 아래와 같다.
여기서 문제는 연결하는 DB마다 커넥션을 연결하는 방법, 쿼리의 문법, 결과를 받는 방법이 모두 다르다는 점이다.
그러면 개발자는 각 DB마다 사용법을 모두 알아야하고, 프로젝트에서 DB를 바꾼다면 기존에 DB와 통신하는 모든 부분을 수정해야하는 문제가 있다.
그래서 등장한게 JDBC이다.
JDBC는 표준 인터페이스이다.
위에서 언급한 어플리케이션 서버와 DB간 통신하는 3가지 과정을 추상화하여 표준 인터페이스를 정의한 것이다.
그러면 각각의 DB회사에서는 이렇게 정의된 표준 인터페이스에 맞춰 라이브러리를 제공하는데 이를 JDBC 드라이버라고 한다.
이렇게 표준 인터페이스를 사용하면 위에서 언급한 문제들이 해결된다.
각 DB마다 사용법을 알아야되는것이아니라 공통화된 표준 사용법이 있으니 모든 DB에 동일한 방법으로 사용할 수 있고, DB를 교체해야 할 경우 사용법이 통일되어 있으니
DB회사에서 제공하는 JDBC 드라이버만 교체해주면 된다.
JDBC의 등장으로 커넥션 연결, 결과를 받는 부분이 통일되었지만 각 DB마다 사용되는 쿼리는 조금씩 다른 부분이 있다.
대표적으로는 각 DB에서 페이징을 처리하는 방법이 다르다는 점이 있다.
어플리케이션과 디비와 통신하는 순서는 아래와 같은데 그중 1번인 커넥션을 연결한다에 관련이 있다.
어플리케이션 서버는 디비와 통신을 할 때 마다 위의 3단계를 거친다. 그중에서 1번에 해당하는 커넥션을 연결하는데 많은 리소스가 소요되고 데이터베이스에 따라서 커넥션을 연결하는데
많은 시간이 드는 경우도 있다. 이와 같은 문제를 해결하기 위해서 디비와 통신할 때 마다 커넥션을 새로 만드는 것이 아니라 서버가 처음 구동할 때 미리 커넥션을 만들어두고
요청이 들어오면 만들어둔 커넥션을 사용하는 방법이 등장하였다. 서버 구동과 동시에 생성한 커넥션을 저장한게 커넥션 풀이다.
이러한 커넥션 풀은 직접 만들어서 관리해도 상관없지만 이미 오픈소스로 성능도 좋고 사용하기도 편한 여러가지 툴이 존재한다. 그중에서 hikaricp가 스프링 부트에서 기본적으로 제공하는
커넥션 풀 관리 툴이다.
DataSource는 커넥션을 획득하는 방법을 추상화한 것이다.
앞서 커넥션 풀이 서버가 구동할 때 사용할 커넥션들을 미리 생성해서 가지고 있는 것이라고 말하였는데 이를 툴이 다양하지만 그 중에서 hikaricp를 스프링이 채택하였다.
그런데 만약에 hikaricp를 사용하다가 다른 커넥션 풀을 사용한다고하면 각각의 커넥션 풀마다 사용법이 다를것이고 이에 따른 코드 수정도 필요하다.
마치 앞서 JDBC를 통한 표준 인터페이스로 사용법을 통일한 것처럼 DataSource라는 표준 인터페이스를 통하여 각기다른 커넥션 풀 툴의 사용법을 통일하여 코드의 수정없이
다른 커넥션 풀을 사용할 수 있게됬다.
커넥션 풀은 서버가 실행할 때 미리 커넥션들으 생성하고 필요할 때 마다 사용하는 것이라고 하였다.
커넥션 풀에 커넥션을 저장 할 때 매인 쓰레드에서 동작하는 것이 아닌 별도의 쓰레드에서 커넥션을 생성해주는데 그 이유는 커넥션을 생성하고 생성한 커넥션을 커넥션 풀에 저장하는 행위는
상대적으로 오래 걸린다. 따라서 별도의 쓰레드에서 오래걸리는 행위를 처리함으로써 매인 어플리케이션 실행속도에 영향을 주지 않게한다.
어플리케이션에서 디비에 요청을 보낼 때 커넥션을 사용하고 이 커넥션을 생성하는데 상대적으로 많은 시간이 요소가되니 서버가 실행할때 미리 여러개의 커넥션을 만들어 저장하는 커넥션 풀을 설정한다.
커넥션 풀에서는 지정한 커넥션의 숫자 만큼 커넥션을 미리 생성하여 저장하는데 이게 오래걸리기 때문에 별도에 쓰레드에서 실행시킴으로써 메인 어플리케이션에 영향을 주지 않는다.
어플리케이션은 디비에 요청을 보낼 때 커넥션 풀에서 커넥션을 가져다 사용하고 사용이 완료되면 커넥션을 반납해야한다.
만약 10개의 커넥션을 가지고 있는 커넥션 풀에서 11개의 요청이 들어오면 대기하고 있던 10개의 커넥션은 각각의 요청을 처리하고 1개의 요청은 다른 요청이 처리가 완료되어 커넥션을 반납할 때 까지 대기한다.
요청을 처리하여 커넥션을 반납하면 반납된 커넥션을 사용하여 대기하고 있던 요청을 처리한다.
이때 커넥션이 반납 될 때까지 기다릴수없으니 보통 대기시간을 지정하여 오버된 요청은 반환시킨다.