본문 바로가기
네이버클라우드/JAVA 웹 프로그래밍

JAVA 46일차 (2023-07-26) 자바 프로그래밍_51. DB 커넥션 풀을 이용한 Connection 재사용하기_개인프로젝트 - 마트 관리 시스템

by prometedor 2023. 7. 26.
## 51. DB 커넥션 풀을 이용한 Connection 재사용하기

- 여러 스레드에서 DB 커넥션 객체를 공유할 때의 문제점 이해
- ThreadLocal을 이용하여 스레드 전용 변수를 만드는 방법
- 풀링 기법을 이용하여 커넥션 재사용하는 방법

 

여러 스레드에서 DB 커넥션 객체를 공유할 때의 문제점 이해

ㄴ 필요 없는 클래스 제거하여 정리

 

ㄴ DataSource 라는 이름의 클래스 파일을 생성

 

DataSource.java

ㄴ DB 커넥션을 관리하고 제공하며, 스레드 별로 DB 커넥션을 보관하도록하는 DataSource.java 클래스 파일 작성

=>

DataSource.java

ㄴ 생성자 추가

 

 

ThreadLocal을 이용하여 스레드 전용 변수를 만드는 방법

DataSource.java

ㄴ ThreadLocal 을 이용하여 스레드 별로 Connection 보관할 저장소 준비

=>

 

DataSource.java

ㄴ 현재 스레드의 Connection 보관소에서 Connection 객체를 꺼내도록 함

=>

ㄴ ConnectionBox를 통해 현재 스레드 보관소에 저장된 Connection 객체를 꺼내도록 함

 

DataSource.java

ㄴ 만약 현재 스레드에 Connection 객체가 보관되어 있지 않다면 새로 생성하도록 함

ㄴ JDBC(Java Database Connectivity) 드라이버를 사용하여 데이터베이스에 연결하는 데 사용

 

DataSource.java

ㄴ connectionBox를 통해 새로 생성한 Connection 객체를 현재 스레드에 보관하도록 함

 

DataSource.java

ㄴ 보관되어 있는 Connection 객체든 새로 생성한 Connection 객체든 리턴하도록 함

 

DataSource.java

ㄴ 스레드가 작업을 끝냈으면, 이 스레드에 보관된 Connection 객체를 remove 메서드를 이용하여 제거하도록 함

=>

DataSource.java

ㄴ connectionBox 에 들어있는 Connection 가 null 이 아니라면 해당 Connection 을 close 한 후 제거하도록 함

 

ServerApp.java

ㄴ AutoCommit 이 true 가 디폴트 값이므로 false 로 변경해주기

 

BoardAddListener.java

ㄴ insert 를 3번 하도록 테스트 해보기

 

ㄴ 목록에서 3개가 등록된 것으로 조회됨

=>

ㄴ 실제 데이터베이스에 추가되지 않음

 

BoardAddListener.java

ㄴ 등록 한 것을 commit 까지 하도록 함

 

ServerApp.java

ㄴ BoardAddListener 클래스에서 생성자에 Connection 도 받기로 변경했으므로 con 추가

=>

ㄴ 목록에서 3개가 등록된 것으로 조회됨

=>

ㄴ 실제 데이터베이스에도 반영됨을 확인할 수 있음

 

BoardAddListener.java

ㄴ 각각 5초동안 잠들도록 해줌

 

BoardAddListener.java

ㄴ 잠든 시간 사이에 다른 클라이언트가 접속해서 rollback 할 경우를 테스트할 것임

 

=>

ㄴ 직원1이 글을 등록하는 도중에 직원2가 글을 등록하면서 rollback 을 해서 직원1이 등록하던 글도 rollback 되는 현상이 발생함

 

DataSource.java

ㄴ 어떤 커넥션이 생성되는지 출력해서 확인하기 위함

 

DataSource.java

ㄴ 제거되는 커넥션 이름을 출력하여 확인하기 위함


MySQLBoardDao.java

ㄴ MySQLBoardDao 에서 Connection 대신 미리 만들어둔 DataSource 를 사용하기 위해 필드에 선언

 

MySQLBoardDao.java

ㄴ Connection -> DataSource 로 변경해주기

 

MySQLBoardDao.java

ㄴ con -> ds.getConnection() 으로 변경

=>

Member , item 도 Board 와 동일하게 설정해주기

=>

MySQLMemberDao.java

=>

ㄴ con -> ds.getConnection() 으로 변경

 

ServerApp.java

ㄴ DataSource 를 사용하기 위해 선언 및 import

 

ServerApp.java

=>

ServerApp.java

ㄴ 해당 코드 잘라내기

=>

DataSource.java

ㄴ AutoCommit 은 디폴트 값이 true 이므로 false 로 변경해주기

 

DataSource.java

ㄴ autoCommit 이 true 라면 con에 대해 autoCommit 을 true 로 설정하여 커넥션을 리턴하고 그 반대는 false 로 설정하여 커넥션을 리턴함

 

DataSource.java

ㄴ 자동 커밋을 true 로 했기 때문에 모든 쿼리가 즉시 커밋되게 됨

 

ServerApp.java

ㄴ con -> ds 로 변경해주기

 

ServerApp.java

ㄴ 해당 코드 삭제

 

ServerApp.java

ㄴ BoardAddListener 클래스의 생성자에 ds 를 넘겨주도록 설정

 

BoardAddListener.java

ㄴ 생성자에도 DataSource 적용

 

BoardAddListener.java

ㄴ con -> ds.getConnection() 으로 변경

 

DataSource.java

ㄴ 스레드에 보관된 커넥션을 사용한다면 해당 문구 출력하도록 함

 

 

=>

=>

ㄴ 로그인 할 때 커넥션이 생성되고, 해당 커넥션이 스레드에 보관됨

ㄴ 리스트를 조회할 때 스레드에 보관된 커넥션 사용

 

=>

ㄴ 새로운 클라이언트가 접속할 경우 새로운 스레드와 새로운 커넥션이 생성됨

 

=>

 

 

MySQLBoardDao.java

ㄴ 자동커밋을 false 로 설정하기

 

MySQLBoardDao.java

ㄴ finally 를 이용해 DataSource 를 clean 해주도록 함 (스레드가 작업을 끝냈으면, 이 스레드에 보관된 Connection 객체를 제거)

 

풀링 기법을 이용하여 커넥션 재사용하는 방법

DataSource.java

ㄴ 커넥션 목록을 유지하기 위한 객체

 

DataSource.java

ㄴ 커넥션 풀에 사용할 수 있는 객체가 있다면, 꺼내도록 함

    => remove(0) : 가장 오래된 연결을 가져와서 제거한 후 해당 값 리턴

 

DataSource.java

ㄴ 새 커넥션이 생성될 경우 해당 문구를 출력하도록 함

 

DataSource.java

 

DataSource.java

ㄴ 스레드가 사용한 DB 커넥션을 다른 스레드에서 사용할 수 있도록 커넥션 풀에 저장함

    => 커넥션 재사용을 위함

=> 스레드에서는 제거하되 사용했던 커넥션을 재사용 하기 위해 커넥션 풀에 저장하는 것

 

DataSource.java

ㄴ 커넥션 풀에 DB 커넥션을 저장하는지 눈으로 확인하기 위해 해당 문구를 출력하도록 함

=>

DataSource.java

 

DataSource.java

 

ServerApp.java

ㄴ DB 커넥션 재활용 테스트를 하기 위해 스레드 2개로 제한

 

 

ㄴ 클라이언트 2명이 접속했으므로 더이상 쓸 수 있는 스레드가 없어서 3번째 클라이언트는 대기

=>

=>

ㄴ 2번째 클라이언트 나감

=>

ㄴ 2번째 클라이언트가 나간 후 3번째 클라이언트가 접속 가능

=>

ㄴ 세 커넥션을 생성하지 않고 2번째 클라이언트가 썼던 2번 스레드를 새롭게 재사용하는 것을 알 수 있음