Spring

[스프링/DataSource] 스프링-DB 1편 2. ConnectionPool, DataSource의 이해

ydin 2024. 1. 30. 13:26

커넥션 풀 이해

위 그림에서 볼 수 있듯이 클라이언트가 서버에 요청을 하고, 커넥션 생성부터 반환까지 복잡한 과정을 거친다.

그래서 커넥션을 새로 만들고 사용하기까지 시간이 많이 소모된다. 하지만 DB를 사용하기 위해서는 커넥션을 필수로 만들어야 하는데, 시간이 오래걸리면 사용자에게 좋지 않은 경험을 줄 수 있다.

그럼 어떻게 하면 커넥션 생성 시간을 줄일 수 있을까? → 커넥션 풀을 사용하자

 

커넥션 풀

커넥션 풀은 이름 그대로 커넥션들을 모아두고 관리하는 풀(수영장 풀)이다.

애플리케이션을 시작하는 시점에 커넥션 풀은 필요한 만큼 커넥션을 미리 확보해서 풀에 보관한다. 보통 기본값으로 10개의 커넥션이 하나의 풀에 있다.

커넥션 풀에 들어 있는 커넥션은 TCP/IP로 DB와 커넥션이 연결되어 있는 상태이므로 언제든지 SQL을 DB에 전달할 수 있다.

  • 커넥션 풀 장점
    • 실무에서는 커넥션 풀 항상 기본으로 사용한다!
    • 커넥션 생성 시간 단축시켜준다
    • 서버당 최대 커넥션 수를 제한해 DB에 무한정 커넥션이 생성되는 것을 막아주어서 DB 보호 효과 o
  • 오픈소스 커넥션 풀
    • 사용성이 편리하고, 성능이 뛰어나서 사용을 추천
    • 최근에는 성능, 사용의 편리함, 안정성 측면에서 검증된 HikariCP를 주로 사용한다
    • 스프링 부트 2.0부터 기본 커넥션 풀이 HikariCP이 기본이다

 

커넥션 풀 사용 및 반환

  • 이제 더이상 DB드라이버를 통해 매번 새로운 커넥션을 획득하지 않는다
  • 커넥션 풀에 이미 생성되어 있는 커넥션을 객체 참조로 그냥 가져다 쓰면 된다
  • 커넥션 풀에 커넥션을 요청하면 커넥션 풀은 자신이 가지고 있는 커넥션 중 하나를 반환하고, 애플리케이션은 로직은 이를 사용하면 된다
  • 커넥션 사용이 끝나면 커넥션 종료가 아닌 살아있는 커넥션을 커넥션 풀에 반환한다
    • 이를 통해 커넥션 재사용이 가능하다

 

 

DataSource 이해

커넥션을 얻는 방법은 JDBC DriverManager를 직접 사용하거나 커넥션 풀을 사용하는 등 다양한 방법이 존재한다.

만약 DriverManager를 사용해 직접 커넥션을 생성해 사용하다가 HikariCP 커넥션 풀로 커넥션 방법을 바꾼다면 어떻게 될까?

→ 이 경우 애플리케이션 코드를 변경해야 할 것이다. 하지만 매번 커넥션 방법을 바꿀 때마다 코드를 변경해야 한다면 시간도 오래 걸리고, 유지보수에 좋지 않을 것이다.

→ 이런 문제에는 보통 추상화로 문제를 해결하는데, 이때 DataSource라는 인터페이스를 이용한다.

 

커넥션 획득 방법의 추상화

자바는 javax.sql.DataSource라는 커넥션을 획득 방법을 추상화한 인터페이스를 제공해 문제를 해결한다.

  • 이제 애플리케이션 로직은 특정 커넥션 방법이 아닌 DataSource에 의존하면 된다
  • 커넥션 풀 구현 기술을 변경하고 싶으면 해당 구현체로 갈아끼우면 된다
  • DriverManager는 DataSource 인터페이스를 사용하지 않기에 직접 DriverManager를 사용해야한다
    • 하지만 스프링에서는 DriverManagerDataSource라는 구현 클래스를 제공해 DriverManager도 DataSource를 통해 사용할 수 있게 해준다

 

void dataSourceDriverManager() throws SQLException {
     DriverManagerDataSource dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);

     Connection con1 = dataSource.getConnection();
     Connection con2 = dataSource.getConnection();
     log.info("connection={}, class={}", con1, con1.getClass());
     log.info("connection={}, class={}", con2, con2.getClass());
}
  • DriverManager는 매번 URL, USERNAME, PASSWORD를 파라미터로 넘겨야 한다.
    • dataSource.getConnection(URL, USERNAME, PASSWORD)
  • 반면에 DataSource는 객체 초기 생성할 때만 파라미터로 넘기고, 커넥션을 획득할 때는 파라미터를 넘기지 않는다.
    • dataSource.getConnection()

 

DataSource의 장점 - 객체의 설정과 사용 분리

  • 설정 : 필요한 속성들(URL, USERNAME, PASSWORD)을 넘겨서 필요한 커넥션을 설정할 수 있다
  • 사용 : 커넥션 사용 시 매번 같은 파라미터를 넘기지 않아도 되고, dataSource.getConnection()만 하면 된다
  • 이는 리포지토리는 DataSource에만 의존하고 다른 속성을 몰라도 된다.

 

Reference

인프런 김영한 - '스프링 DB 1편 - 데이터 접근 핵심 원리'