필기노트

김영한 스프링 강의 요약 - 커넥션풀과 데이터소스 이해 본문

김영한 강의 요약

김영한 스프링 강의 요약 - 커넥션풀과 데이터소스 이해

우퐁코기 2024. 1. 26. 08:48
반응형

1. 커넥션 풀 이해

1) 데이터베이스 커넥션을 매번 획득

커넥션을 새로 만드는 것은 과정도 복잡하고 시간도 많이 많이 소모되는 일이다.

이런 문제를 한번에 해결하는 아이디어가 바로 커넥션을 미리 생성해두고 사용하는 커넥션 풀이라는 방법이다.

 

2) 커넥션 풀 초기화와 연결 상태

  • 애플리케이션을 시작하는 시점에 커넥션 풀은 필요한 만큼 커넥션을 미리 확보해서 풀에 보관한다. 기본값은 보통 10개이다. 실무에서는 항상 기본으로 사용한다.
  • 커넥션 풀에 들어 있는 커넥션은 TCP/IP로 DB와 커넥션이 연결되어 있는 상태이기 때문에 언제든지 즉시 SQL을 DB에 전달할 수 있다.

 

3) 커넥션 풀 사용

  • 애플리케이션 로직에서 이제는 DB 드라이버를 통해서 새로운 커넥션을 획득하는 것이 아니다.
  • 이제는 커넥션 풀을 통해 이미 생성되어 있는 커넥션을 객체 참조로 그냥 가져다 쓰기만 하면 된다.
  • 애플리케이션 로직은 커넥션 풀에서 받은 커넥션을 사용해서 SQL을 데이터베이스에 전달하고 그 결과를 받아서 처리한다.
  • 커넥션을 모두 사용하고 나면 이제는 커넥션을 종료하는 것이 아니라, 다음에 다시 사용할 수 있도록 해당 커넥션 을 그대로 커넥션 풀에 반환하면 된다.

 


2. DataSource 이해

커넥션을 획득하는 방법은 앞서 학습한 JDBC DriverManager 를 직접 사용하거나, 커넥션 풀을 사용하는 방법이 존재한다. DataSource 는 커넥션을 획득하는 방법을 추상화하는 인터페이스이다.

 

  • 대부분의 커넥션 풀은 DataSource 인터페이스를 이미 구현해두었다. 따라서 개발자는 DBCP2 커넥션 풀, HikariCP 커넥션 풀 의 코드를 직접 의존하는 것이 아니라 DataSource 인터페이스에만 의존하도록 애플리 케이션 로직을 작성하면 된다. 
  • 커넥션 풀 구현 기술을 변경하고 싶으면 해당 구현체로 갈아끼우기만 하면 된다.
  • 성능과 사용의 편리함 측면에서 최근에는 hikariCP를 주로 사용한다.
  • 이 인터페이스의 핵심 기능은 커넥션 조회 하나이다.
public interface DataSource {
    Connection getConnection() throws SQLException;
}

 


3. DataSource 적용

@Slf4j
public class MemberRepositoryV1 {
    
    private final DataSource dataSource;
    
    public MemberRepositoryV1(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    
    //save()...
    //findById()...
    //update()....
    //delete()....
    
    private void close(Connection con, Statement stmt, ResultSet rs) {
        JdbcUtils.closeResultSet(rs);
        JdbcUtils.closeStatement(stmt);
        JdbcUtils.closeConnection(con);
    }
    
    private Connection getConnection() throws SQLException {
        Connection con = dataSource.getConnection();
        log.info("get connection={}, class={}", con, con.getClass());
        return con;
    }
    
}

1) DataSource 의존관계 주입

  • 외부에서 DataSource를 주입 받아서 사용한다. 이제 직접 만든 DBConnectionUtil을 사용하지 않 아도 된다.
  • DataSource는 표준 인터페이스 이기 때문에 DriverManagerDataSource에서 HikariDataSource로 변경되어도 해당 코드를 변경하지 않아도 된다.

2) JdbcUtils 편의 메서드

  • 스프링은 JDBC를 편리하게 다룰 수 있는 JdbcUtils라는 편의 메서드를 제공한다.
  • JdbcUtils을 사용하면 커넥션을 좀 더 편리하게 닫을 수 있다.

4. DataSource 테스트

@Slf4j
class MemberRepositoryV1Test {
    
    MemberRepositoryV1 repository;
    
    @BeforeEach
    void beforeEach() throws Exception {
        //기본 DriverManager - 항상 새로운 커넥션 획득 
        //DriverManagerDataSource dataSource =
        // new DriverManagerDataSource(URL, USERNAME, PASSWORD);

        //커넥션 풀링: HikariProxyConnection -> JdbcConnection 
        HikariDataSource dataSource = new HikariDataSource(); 
        dataSource.setJdbcUrl(URL); 
        dataSource.setUsername(USERNAME); 
        dataSource.setPassword(PASSWORD);

        repository = new MemberRepositoryV1(dataSource);
    }

    @Test
    void crud() throws SQLException, InterruptedException {
        log.info("start");

        //save
        Member member = new Member("memberV0", 10000);
        repository.save(member);

        //findById
        Member memberById = repository.findById(member.getMemberId());
        assertThat(memberById).isNotNull();

        //update: money: 10000 -> 20000
        repository.update(member.getMemberId(), 20000);
        Member updatedMember = repository.findById(member.getMemberId());
        assertThat(updatedMember.getMoney()).isEqualTo(20000);
    
        //delete
        repository.delete(member.getMemberId());
        assertThatThrownBy(() -> repository.findById(member.getMemberId()))
                .isInstanceOf(NoSuchElementException.class);
    }
}
  • MemberRepositoryV1은 DataSource 의존관계 주입이 필요하다.
get connection=HikariProxyConnection@xxxxxxxx1 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx2 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx3 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx4 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx5 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx6 wrapping conn0: url=jdbc:h2:...user=SA
  • 커넥션 풀 사용시 conn0 커넥션이 재사용 된 것을 확인할 수 있다.
  • 테스트는 순서대로 실행되기 때문에 커넥션을 사용하고 다시 돌려주는 것을 반복한다. 따라서 conn0만 사용된다.
  • 웹 애플리케이션에 동시에 여러 요청이 들어오면 여러 쓰레드에서 커넥션 풀의 커넥션을 다양하게 가져가는 상황 을 확인할 수 있다.

 


 

스프링 DB 1편 - 데이터 접근 핵심 원리 강의 - 인프런

백엔드 개발에 필요한 DB 데이터 접근 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 DB 접근 기술의 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 백엔

www.inflearn.com

반응형
Comments