스프링 부트 3.2.2 버전을 기준으로 작성됨
H2 데이터베이스 Version 2.2.224 (2023-09-17)
데이터베이스 커넥션 획득 과정은 매우 복잡하다.
커넥션 조회, TCP/IP 3way handshake 연결, 인증 ,세션생성.. 등
이러한 문제를 해결하는 커넥션 풀이 등장하였다.
커넥션 풀은 커넥션을 미리 생성해두고 관리한다.
각 커넥션들은 TCP/IP 연결이 된 상태이기에
언제든지 SQL 전달이 가능하다.
사용이 끝나면 커넥션 풀에 반환한다.
여기서 DriverManager를 통해서 커넥션을 획득하다가
커넥션 풀을 사용하는 방법으로 변경할려면?
-> 커넥션을 획득하는 애플리케이션 코드도 함께 변경해야한다.
그렇기에 커넥션을 획득하는 방법을 추상화하는 인터페이스를 사용하여 언제든지 다른 방법으로 바꾸어도 문제없도록 한다.
애플리케이션 로직에서는 커넥션 획득하는 메서드만 알게끔 하면 된다.
자바에서 제공하는 javax.sql.DataSource
인터페이스
이 인터페이스의 핵심 기능 : 커넥션 조회
스프링이 제공하는 DataSource
가 적용된 DriverManager
인 DriverManagerDataSource
를 사용
@Test
void dataSourceDriverManager() throws SQLException {
//DriverManagerDataSource - 항상 새로운 커넥션을 획득
DriverManagerDataSource dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);
useDataSource(dataSource);
}
private void useDataSource(DataSource dataSource) throws SQLException {
Connection con1 = dataSource.getConnection();
Connection con2 = dataSource.getConnection();
log.info("connection={}, class={}", con1, con1.getClass());
log.info("connection={}, class={}", con2, con2.getClass());
}
설정
DataSource
를 만들고 필요한 속성들을 사용해서 URL
, USERNAME
, PASSWORD
같은 부분을 입력하는 것을 말한다.
설정과 관련된 속성들은 한 곳에 있는것이 변경에 유연하다. (DataSource
가 만들어지는 시점에 속성들을 미리 넣어두는 것)
사용
DataSource
의 getConnection()
만 호출@Test
void dataSourceConnectionPool() throws SQLException, InterruptedException {
//커넥션 풀링
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setMaximumPoolSize(10); // 사이즈 설정
dataSource.setPoolName("MyPool"); // 풀 이름
useDataSource(dataSource);
Thread.sleep(1000);
}
커넥션 풀에서 커넥션 생성 작업은 애플리케이션 실행 속도에 영향을 주지 않기 위해 별도의 쓰레드에서 작동
별도의 쓰레드에서 동작하기 때문에 테스트가 먼저 종료되어버리기에 Thread.sleep 을 통해 대기시간을 주어야 커넥션 생성 로그 확인 가능
#커넥션 풀 초기화 정보 출력
HikariConfig - MyPool - configuration:
HikariConfig - maximumPoolSize................................10
HikariConfig - poolName................................"MyPool"
#커넥션 풀 전용 쓰레드가 커넥션 풀에 커넥션을 10개 채움
[MyPool connection adder] MyPool - Added connection conn0: url=jdbc:h2:..
user=SA
...
#커넥션 풀에서 커넥션 획득1
ConnectionTest - connection=HikariProxyConnection@1234 wrapping conn0:
url=jdbc:h2:tcp://localhost/~/test user=SA, class=class
com.zaxxer.hikari.pool.HikariProxyConnection
...
MyPool - After adding stats (total=10, active=2, idle=8, waiting=0)
total
: 최대 갯수
active
: 사용중인 커넥션
idle
: 풀에서 대기 상태인 커넥션
정리하면서 혼자 헷갈린 부분을 정리한다.
기본 DriverManagerDataSource 와 커넥션 풀 사용 예제에서 보면 왜 DataSource인터페이스를 사용하지 않나 생각할 수도 있는데
사실 MemberRepository에서 dataSource를 생성자로 받아 실질적인 비지니스 로직을 실행하고 있다.
DriverManagerDataSource에서 얻은 dataSource를 쓰던지
HikariDataSource에서 얻은 dataSource를 쓰던지 MemberRepository는 DataSource 인터페이스에 의존하기에 사용하고자 하는 것을 주입받아 사용하면 된다.
public class MemberRepositoryV1 {
private final DataSource dataSource;
public MemberRepositoryV1(DataSource dataSource) {
this.dataSource = dataSource;
}
🔖 학습내용 출처