[Spring] Connection Pool / DataSource

manx·2022년 7월 5일
0

spring

목록 보기
20/22

인프런 '스프링 DB 1편' - 김영한님의 강의 내용입니다.

Connection Pool

이전에 JDBC 만을 이용해 CRUD를 할 경우 SQL을 날릴 때 마다 DB Driver가 DB와 TCP/IP 커넥션으로 연결했다.
이 과정에서 3 way handshake 같은 네트워크 동작이 발생하는데, 이는 과정도 복잡하고 시간도 많이 소요돼 응답 속도에 악영향을 끼친다.
그래서 나온 아이디어가 바로 Connection Pool 이다.

DB와 연결을 미리 해 놓은 뒤 해당 Connection을 Connection Pool에 담아 놓은 뒤 유저가 필요할 때 마다 사용하게 하는 방식이다.

커넥션 풀 오픈소스는 여러개가 있지만, HikariCP 를 주로 사용한다.

DataSource

JAVA에서는 DriverManager, HikariCP 와 같이 데이터베이스와 연결하는 방법을 추상화한 DataSource 인터페이스를 제공한다. (추상화가 뭔지 모른다면, '오브젝트' 정리한 내용을 참고하기 바란다.)


기존 CRUD를 변경한 코드

close 메서드

바로 전 포스트에서 close를 try-catch 문으로 지저분하게 처리했지만, JdbcUtils에서 closeResultSet, closeConnection, closeStatement 과 같은 편의 메서드를 제공해준다.

private void close(Connection con, Statement stmt, ResultSet rs) {
        JdbcUtils.closeResultSet(rs);
        JdbcUtils.closeConnection(con);
        JdbcUtils.closeStatement(stmt);
    }

connection

쿼리를 날릴 때 마다 getConnection() 메서드에서 URL, USERNAME, PASSWORD를 넣어 Connection을 만드는 것이 아닌 DataSource를 주입받아 한번의 연결로 사용할 수 있다.
이 때 한번의 설정으로 필요 메서드만 호출해서 사용할 수 있으므로 설정과 사용을 분리할 수 있다.

public class MemberRepositoryV1 {

    private final DataSource dataSource;

    public MemberRepositoryV1(DataSource dataSource) {
        this.dataSource = dataSource;
    }
	
    // ... CRUD ...
    
    private Connection getConnection() throws SQLException {
        Connection con = dataSource.getConnection();
        log.info("get connection={}, class={}", con, con.getClass());
        return con;
    }
}

DataSource DI

setJdbcUrl, setUsername, setPassword를 통해 최초 한번 DB와 Connection을 생성한 뒤 필요한 경우에 가져다 쓸 수 있다.
그리고 또한 HikariDataSource가 DataSource를 구현한 것이므로 Repository의 코드에서는 수정이 불필요하다.
DI + OCP, GOOD!

@Slf4j
class MemberRepositoryV1Test {

    MemberRepositoryV1 repository;

    @BeforeEach
    void beforEach() {
//        DriverManagerDataSource dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);

        // 커넥션 풀링
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(URL);
        dataSource.setUsername(USERNAME);
        dataSource.setPassword(PASSWORD);
        repository = new MemberRepositoryV1(dataSource);
    }
}

Conenction Pool을 통해 쿼리를 날릴 때 마다 DB와 연결해야 하는 번거로움을 제거했고, DataSource를 사용해 Connection 방법을 추상화 함으로써 Repository와 Connection 클래스의 의존 관계를 느슨하게 변경할 수 있었다.

profile
Back-end Developer

0개의 댓글