데이터베이스 커넥션 획득 과정
1. 애플리케이션에서 DB 드라이버를 통해 커넥션 조회
2. DB 드라이버는 DB와 TCP/IP 커넥션을 연결한다.
3. DB 드라이버는 TCP/IP 커넥션이 연결되면 ID, PW와 기타 정보를 DB에 전달한다.
4. DB는 ID, PW를 통해 내부 인증을 완료하고, 내부에 DB 세션을 생성한다.
5. DB는 커넥션 생성이 완료되었다는 응답을 보낸다.
6. DB 드라이버는 커넥션 객체를 생성해서 클라이언트에 반환한다.
이처럼 커넥션을 생성하는 과정은 복잡하고, 시간이 많이 소모되는 일이다. 또한, 애플리케이션 서버에서도 TCP/IP 커넥션을 새로 생성하기 위해 리소스를 매번 사용해야 한다. 따라서 전반적인 응답속도에 영향을 준다.
이를 해결하기 위해 일정 개수의 커넥션을 미리 생성하여 보관하는 커넥션 풀 방법을 사용한다.
커넥션 풀
어플리케이션을 시작하는 시점에 필요한 만큼의 커넥션을 미리 확보해서 커넥션풀이 보관한다. ( 커넥션 수 기본값 10개 )
이렇게 하면, 커넥션 풀에 들어있는 커넥션은 TCP/IP로 DB와 커넥션이 연결되어 있는 상태이기 때문에 요청 즉시 SQL을 DB로 전달할 수 있다. 애플리케이션에 커넥션 풀에 커넥션을 요청하면 커넥션풀에서 가지고 있는 커넥션 중 하나를 반환한다. 커넥션 풀의 커넥션을 받아서 사용하고, 사용이 끝나면 커넥션을 종료하는것이 아니라 커넥션 풀에 반환한다.
커넥션 풀은 단순한 개념이기 때문에 직접 구현할 수도 있지만, 성능 좋은 오프소스 커넥션 풀이 많기 때문에 오픈소스를 사용한다. 스프링부트 2.0부터는 현시점에서 가장 성능이 좋고 편리한 HikariCP를 기본으로 사용한다.
DataSource
커넥션을 획득하는 방법은 DriverManager을 통해 커넥션을 생성하여 획득하는 방법과, 커넥션 풀을 이용하는 방법 등 다양한 방법들이 있다. 그런데 만약 커넥션을 획득하는 방법을 DriverManager에서 커넥션 풀 방식으로 바꾸거나, 커넥션 풀 오픈소스를 사용하다가 다른 커넥션 풀 오픈소스로 변경하는 경우 각각의 방법에 따라 커넥션을 획득하는 애플리케이션 코드를 변경해야 할 것이다. DriverManager 또는 특정 커넥션 풀에 의존하기 때문이다.
자바에서는 이러한 문제를 해결하기 위해 커넥션 획득 방법을 추상화 하는 javax.sql.DataSource 라는 인터페이스를 제공한다. 이 인터페이스의 기능은 커넥션 획득 단 하나이다.
public interface DataSource {
Connection getConnection() throws SQLException;
}
대부분의 커넥션 풀은 DataSource 인터페이스를 이미 구현해 두었기 때문에 개발자는 특정 커넥션 풀의 코드에 직접 의존하는 것이 아니라 DataSource 인터페이스에만 의존하도록 애플리케이션 로직을 작성하면 된다.
그러나 DriverManager은 DataSource 인터페이스를 사용하지 않고 DriverManager을 직접 사용해야 한다. 이 문제를 해결하기 위해 스프링은 DriverManager도 DataSource를 통해 사용할 수 있도록 DriverManagerDataSource라는 클래스를 제공한다.
DriverManagerDataSource
기존에 DriverManager을 통해 커넥션을 획득하던 방법
Connection con = DriverManager.getConnection(URL, USERNAME, PASSWORD);
DriverManagerDataSource를 통해 커넥션을 획득하는 방법
이 방법은 DataSource를 선언할 때만 URL, USERNAME, PASSWORD 같은 속성을 입력하고, 이후에는 생성한 dataSource에만 의존하면 된다는 장점도 있다. (설정과 사용 분리)
DriverManagerDataSource dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);
Connection con = dataSource.getConnection();
Connection Pool
커넥션 풀 DataSource를 사용하고, 여러 가지 속성을 지정해 준다.
사용은 똑같이 dataSource.getConnection()으로 하면 된다.
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setMaximumPoolSize(10);
dataSource.setPoolName("MyPool");
DataSource 사용
외부에서 DataSource를 주입받아서 사용한다.
public class MemberRepository{
private final DataSource dataSource;
public MemberRepository(DataSource dataSource) {
this.dataSource = dataSource;
}
//생략
}
JdbcUtils
스프링이 제공하는 JDBC를 편리하게 다룰 수 있는 편의 메서드이다. 이 메서드를 이용해서 커넥션을 좀 더 편리하게 닫을 수 있다.
private void close(Connection con, Statement stmt, ResultSet rs) {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(stmt);
JdbcUtils.closeConnection(con);
}
(참고) 인프런 - 김영한님 스프링 DB
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-1/dashboard
'Database > 데이터 접근 기술' 카테고리의 다른 글
[SQL/Mysql, MariaDB] 드라이버 연결 (0) | 2023.07.25 |
---|---|
[MyBatis] 동적쿼리, 기타 문법 (0) | 2023.05.15 |
[MyBatis] 마이바티스 기본 사용법 (2) | 2023.05.15 |
[Jdbc] JdbcTemplate 사용법 및 적용예제 (0) | 2023.05.04 |
[JDBC] 자바 데이터베이스 표준 (0) | 2023.05.01 |