6주차 Unit 4.3 — DB 세션과 연결 구조

Psj·2026년 5월 29일

F-lab

목록 보기
196/239

Unit 4.3 — DB 세션과 연결 구조

F-LAB JAVA · 6주차 · Phase 4 · Connection Pool과 DB 세션


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • DB 연결 절차 5단계 는?
  • DB 세션 이란?
  • 세션 = 트랜잭션 단위 의 의미는?
  • 한 Connection 에서 동시 두 트랜잭션 가능한가?
  • 풀의 Connection N 개 = DB 세션 N 개 인가?
  • 세션 종료 방식은?
  • DB 입장에서 풀이 어떻게 보이나 ?
  • Connection vs Session 차이는?
  • 세션 한계와 풀 크기 관계는?

🎯 핵심 한 문장

DB 연결은 TCP 연결 → 세션 생성 → SQL 실행 → 트랜잭션 종료 → 연결 종료의 5단계로 진행되며, 한 Connection 은 하나의 DB 세션과 1:1 매핑되어 동시에 두 트랜잭션을 진행할 수 없고, 따라서 커넥션 풀의 Connection 100 개는 DB 입장에서 세션 100 개로 보인다.
DB 연결 절차는 (1) 클라이언트 ↔ DB 서버 TCP 연결, (2) DB 가 세션 생성 (트랜잭션 단위), (3) 클라이언트 → SQL 전달, 세션이 실행, (4) 세션이 트랜잭션 시작 → commit/rollback 으로 종료, (5) 사용자가 connection close 또는 DB 관리자가 세션 종료다.
세션 은 DB 서버가 클라이언트별로 할당하는 자원 단위로, 트랜잭션 컨텍스트·캐시·임시 데이터 등을 보관한다.
한 Connection 은 하나의 DB 세션과 1:1 매핑 되며, 한 세션은 동시에 한 개의 트랜잭션만 진행할 수 있어 한 Connection 에서 두 트랜잭션 동시 진행은 불가능 하다.
따라서 애플리케이션이 커넥션 풀에 Connection 100 개를 둔다면 DB 서버는 세션 100 개를 들고 있는 것 이며, 풀 크기 결정 시 DB 의 max_connections 한계를 반드시 고려해야 한다.

비유 — 호텔 객실 (세션) 과 투숙객 (Connection)

DB 세션 = 호텔 객실:

연결 절차 (5단계):
  1. 호텔 도착 (TCP 연결)
  2. 체크인 — 객실 배정 (세션 생성)
  3. 활동 (SQL 실행)
  4. 일정 (트랜잭션) — commit/cancel
  5. 체크아웃 (연결 종료)

Connection ↔ 세션 (1:1):
  - 투숙객 1명 = 객실 1개
  - 한 객실에 한 일정 (동시 두 트랜잭션 X)
  - 동시 작업하려면 객실 2개

풀 100 개 = 객실 100 개:
  - 호텔 관점:
    - 객실 100개 점유
    - 메모리/자원
    - 다른 손님 못 받음

max_connections:
  - 호텔 객실 한계 (151)
  - 초과 시 거부

DB 입장:
  - 풀이 보이지 않음
  - 그냥 N 개 세션
  - 누구든 같음

→ 연결 5단계 + Connection ↔ Session 1:1 + 풀 N 개 = DB 세션 N 개.


🧭 9개 섹션 로드맵

1. DB 연결 5단계
2. DB 세션이란
3. 세션 = 트랜잭션 단위
4. Connection ↔ Session 1:1
5. 한 Connection 두 트랜잭션 불가
6. 풀 N개 = 세션 N개
7. 세션 종료 방식
8. DB 입장의 풀
9. 면접 + 자기 점검

1️⃣ DB 연결 5단계

1.1 5단계 절차

DB 연결 5단계:

1. TCP 연결 (클라 → DB)
2. 세션 생성 (DB 가 할당)
3. SQL 실행 (요청·응답)
4. 트랜잭션 종료 (commit/rollback)
5. 연결 종료 (close)

1.2 1단계 — TCP 연결

1. TCP 연결:

  클라이언트 ↔ DB 서버:
    - TCP 3-way handshake
    - 네트워크 채널 수립

→ Unit 4.1 비용

1.3 2단계 — 세션 생성

2. 세션 생성:

  DB:
    - 인증 (ID/PW)
    - 세션 객체 생성
    - 메모리 할당
    - 세션 ID 부여

1.4 3단계 — SQL 실행

3. SQL 실행:

  클라이언트 → DB:
    - SQL 전송
  DB → 클라이언트:
    - 결과 반환

  세션 안에서 수행

1.5 4단계 — 트랜잭션 종료

4. 트랜잭션 종료:

  세션이:
    - 트랜잭션 시작 (BEGIN)
    - SQL 실행
    - commit (확정) 또는 rollback (취소)

  여러 트랜잭션 가능 (순차)

1.6 5단계 — 연결 종료

5. 연결 종료:

  종료 주체:
    - 클라이언트: connection.close()
    - DB 관리자: 세션 강제 종료
    - 타임아웃 (idle)

  → 세션 해제, TCP 종료

1.7 ILIC 의 맥락

DB 연결 5단계 (ILIC)

ILIC backend → MySQL:

  1. TCP 연결:
     - backend → mysql:3306
     - 3-way handshake
  
  2. 세션 생성:
     - 인증 (ilic_user/pwd)
     - 세션 ID 부여
     - 메모리 할당
  
  3. SQL 실행:
     - SELECT * FROM shipments WHERE id = 1
     - 결과 반환
  
  4. 트랜잭션 종료:
     - INSERT/UPDATE/DELETE
     - commit
  
  5. 연결 종료:
     - close() (또는 풀로 반환)
     - 세션 해제

→ Connection Pool 에선 5번 거의 X (재사용)

1.8 자기 점검 답변

DB 연결 절차 5단계는?

:
1. 5단계:

  • TCP/세션/SQL/트랜잭션/종료
  1. TCP:

    • handshake
  2. 세션:

    • DB 가 생성
  3. 종료:

    • close 또는 강제

2️⃣ DB 세션이란

2.1 세션

DB 세션:

  DB 가 클라이언트에 할당:
    - 자원 단위
    - 메모리/상태
    - 트랜잭션 컨텍스트

2.2 세션의 내용

세션의 내용:

  - 세션 ID
  - 인증된 사용자
  - 현재 데이터베이스
  - 트랜잭션 상태
  - 임시 테이블
  - 세션 변수
  - 캐시 (PGA 등)

2.3 격리

세션 격리:

  세션끼리:
    - 독립
    - 다른 세션 메모리 X
    - 다른 세션 트랜잭션 X

→ DB 가 격리 보장

2.4 DB 자원

DB 서버 자원:

  세션마다:
    - 메모리 (수 MB)
    - 백그라운드 프로세스 (Oracle)
    - 파일 디스크립터

→ 무한 X (max_connections)

2.5 ILIC 의 맥락

DB 세션 (ILIC MySQL)

ILIC MySQL 세션 확인:

  -- 현재 세션 목록
  SHOW PROCESSLIST;
  
  -- 결과
  +----+-----------+------+----+-------+---------+
  | Id | User      | Host | DB | Time  | Command |
  +----+-----------+------+----+-------+---------+
  | 10 | ilic_user | ...  |ilic| 0     | Sleep   |
  | 11 | ilic_user | ...  |ilic| 1     | Query   |
  | 12 | ilic_user | ...  |ilic| 0     | Sleep   |
  | ...
  +----+-----------+------+----+-------+---------+
  
  HikariCP 풀이 maximum=20:
    - 약 20개 세션 (PROCESSLIST)
    - 각각 자원 사용 (메모리 등)

2.6 자기 점검 답변

DB 세션이란?

:
1. 세션:

  • DB 가 할당한 자원
  1. 내용:

    • 메모리/상태/트랜잭션
  2. 격리:

    • 세션 간 독립
  3. 자원:

    • 메모리/프로세스

3️⃣ 세션 = 트랜잭션 단위

3.1 트랜잭션 단위

세션 = 트랜잭션 단위:

  한 세션:
    - 한 번에 한 트랜잭션
    - 순차 진행
    - commit/rollback 으로 종료

3.2 트랜잭션 흐름

트랜잭션 흐름 (한 세션):

  세션 생성
    ↓
  트랜잭션1 시작 → SQL → commit
    ↓
  트랜잭션2 시작 → SQL → rollback
    ↓
  트랜잭션3 시작 → SQL → commit
    ↓
  세션 종료

3.3 autocommit

autocommit:

  JDBC 기본: autocommit = true
    - 각 SQL = 자동 commit
    - 트랜잭션 짧음

  명시적 트랜잭션:
    - autoCommit = false
    - 명시적 commit/rollback

3.4 트랜잭션 상태

세션의 트랜잭션 상태:

  - 트랜잭션 미시작 (idle)
  - 트랜잭션 진행 (active)
  - 대기 (waiting on lock)

→ 세션이 추적

3.5 ILIC 의 맥락

// 세션의 트랜잭션 (ILIC)
@Service
public class ShipmentService {
    
    @Transactional   // 한 트랜잭션
    public void createShipment(Shipment s) {
        shipmentDao.add(s);                  // SQL1
        bookingDao.updateStatus(s.getId());   // SQL2
        // 같은 세션, 한 트랜잭션
        // 메서드 끝 → commit
    }
    
    // 메서드 호출마다:
    // 1. Connection 빌림 (풀에서, = 세션 1개)
    // 2. 트랜잭션 시작
    // 3. SQL1, SQL2 (같은 세션)
    // 4. commit (트랜잭션 종료)
    // 5. Connection 반환 (= 세션 유지, 풀에)
    
    ShipmentDao shipmentDao;
    BookingDao bookingDao;
}
class ShipmentDao { void add(Shipment s) {} }
class BookingDao { void updateStatus(Long id) {} }
class Shipment { Long getId() { return null; } }

3.6 자기 점검 답변

세션 = 트랜잭션 단위의 의미는?

:
1. 트랜잭션 단위:

  • 한 번에 한 트랜잭션
  1. 흐름:

    • 순차 진행
  2. autocommit:

    • 기본 true
  3. 상태:

    • 세션이 추적

4️⃣ Connection ↔ Session 1:1

4.1 1:1 매핑

Connection ↔ Session:

  한 Connection (애플리케이션)
       ↕ 1:1
  한 Session (DB)

  - Connection 만들 때 세션 생성
  - Connection 닫을 때 세션 해제

4.2 매핑 의미

매핑 의미:

  애플리케이션 Connection:
    = DB 서버 Session

  → 둘이 같은 것의 양면

4.3 풀의 Connection

풀의 Connection:

  HikariCP 풀에 N 개 Connection:
    - DB 에 N 개 세션
    - 1:1

→ 풀 ≒ DB 세션 묶음

4.4 시각화

시각화:

[애플리케이션]                    [DB 서버]
┌─────────────────┐              ┌────────────────┐
│ HikariPool      │              │ Sessions       │
│ ┌─────────────┐ │  TCP 연결    │ ┌────────────┐ │
│ │ Conn 1      │ │←─────────────│→│ Session 1  │ │
│ │ Conn 2      │ │←─────────────│→│ Session 2  │ │
│ │ Conn 3      │ │←─────────────│→│ Session 3  │ │
│ │ ...         │ │              │ │ ...        │ │
│ │ Conn N      │ │←─────────────│→│ Session N  │ │
│ └─────────────┘ │              │ └────────────┘ │
└─────────────────┘              └────────────────┘

→ N : N 짝

4.5 ILIC 의 맥락

Connection ↔ Session 1:1 (ILIC)

ILIC HikariCP (maximum=20):
  - 풀에 Connection 20개
  - MySQL 에 Session 20개

  애플리케이션 측:
    - Connection 객체 20개 (메모리)
    - 풀이 관리

  DB 측 (MySQL):
    - Session 20개 (메모리)
    - PROCESSLIST 에 20행

  애플리케이션이 풀 크기 늘리면:
    - Connection ↑ → Session ↑
    - DB 부담 증가
    - max_connections 고려

→ 1:1 이므로 풀 크기 = DB 세션 수

4.6 자기 점검 답변

Connection ↔ Session 1:1 인가?

:
1. 1:1 매핑:

  • Connection = Session
  1. 의미:

    • 같은 것의 양면
  2. 풀 N:

    • DB 세션 N
  3. 시각화:


5️⃣ 한 Connection 두 트랜잭션 불가

5.1 불가능

한 Connection 두 트랜잭션 동시:

  → 불가능

  이유:
    - 세션 = 트랜잭션 단위
    - 한 세션 = 한 트랜잭션

5.2 시도 시

시도 시:

  같은 Connection 으로:
    - 트랜잭션1 진행 중
    - 트랜잭션2 시작?
    - → 트랜잭션1 영향 받음

  → 트랜잭션 격리 깨짐

5.3 멀티스레드

멀티스레드 + 같은 Connection:

  스레드 A: 트랜잭션 A
  스레드 B: 같은 Connection 으로 트랜잭션 B
    → 위험!
  
  → Connection 은 스레드 안전 X

5.4 해결

해결:

  다른 트랜잭션 동시 진행:
    - 다른 Connection
    - 다른 세션

  → 풀에서 두 개 빌림

5.5 한 트랜잭션 = 한 Connection

한 트랜잭션 = 한 Connection:

  트랜잭션 시작:
    - Connection 빌림 (세션 잡음)
  
  트랜잭션 중:
    - 같은 Connection 유지
    - 다른 작업 못 끼어듦
  
  commit/rollback:
    - Connection 반환

5.6 ILIC 의 맥락

// 한 Connection 두 트랜잭션 불가 (ILIC)
@Service
public class ShipmentService {
    
    @Transactional
    public void processBooking(Booking b) {
        // 이 메서드 실행 동안:
        // - Connection 1개 점유 (트랜잭션 A)
        // - 같은 Connection 으로 다른 트랜잭션 동시 X
        
        shipmentDao.add(b.getShipment());     // SQL (트랜잭션 A)
        bookingDao.save(b);                    // SQL (트랜잭션 A)
        // 같은 Connection
        // 메서드 끝 → commit
    }
    
    // 다른 트랜잭션 동시 진행하려면:
    @Async   // 다른 스레드 + 다른 Connection
    public void asyncTask() {
        // 다른 Connection 빌림 → 다른 세션 → 별도 트랜잭션
    }
    ShipmentDao shipmentDao;
    BookingDao bookingDao;
}
class Booking { Object getShipment() { return null; } }
class ShipmentDao { void add(Object o) {} }
class BookingDao { void save(Object o) {} }

5.7 자기 점검 답변

한 Connection 에서 동시 두 트랜잭션 가능한가?

:
1. 불가능:

  • 세션 = 트랜잭션 단위
  1. 이유:

    • 한 세션 한 트랜잭션
  2. 멀티스레드:

    • 스레드 안전 X
  3. 해결:

    • 다른 Connection

6️⃣ 풀 N개 = 세션 N개

6.1 풀 N = 세션 N

풀 N 개 Connection
   = DB N 개 세션

  - 1:1 매핑 (섹션 4)
  - 풀 늘리면 세션 늘어남

6.2 DB 입장

DB 입장:

  애플리케이션 풀 모름:
    - 그냥 N 개 클라이언트
    - 각자 세션
    - 자원 할당

6.3 max_connections

max_connections:

  DB 의 최대 세션 한계:
    - MySQL: 151 (기본)
    - PostgreSQL: 100 (기본)
    - 늘릴 수 있지만 자원 ↑

→ 풀 크기 + 다른 클라이언트 ≤ max

6.4 여러 서버

여러 애플리케이션 서버:

  ILIC backend 3대 × 풀 20 = 60 세션
  + admin 서버 5
  + 배치 서버 10
  = 75 세션

  → DB max_connections > 75 필요
  → 여유분 (운영/관리자) 도 고려

6.5 ILIC 의 맥락

풀 N = 세션 N (ILIC)

ILIC 환경:
  - MySQL max_connections = 151
  
  - backend (1대) × HikariCP (20) = 20 세션
  - 배치 작업 풀 (5) = 5 세션
  - 운영 도구 (10) = 10 세션
  - 합 = 35 세션 (안전)

  확장 시:
  - backend 5대 × 20 = 100
  - 다른 것 + 25 = 125
  - max (151) 까지 여유 26

  → 스케일 아웃 시 max_connections 고려
  → DB 측 설정도 함께 (my.cnf)

6.6 자기 점검 답변

풀의 Connection N 개 = DB 세션 N 개인가?

:
1. N = N:

  • 1:1
  1. DB 입장:

    • N 개 클라이언트
  2. max_connections:

    • DB 한계
  3. 여러 서버:

    • 총 세션 고려

7️⃣ 세션 종료 방식

7.1 종료 방식

세션 종료:

1. 클라이언트가 close
2. 타임아웃 (idle)
3. DB 관리자 강제 (KILL)
4. DB 서버 종료
5. 네트워크 끊김

7.2 클라이언트 close

// 클라이언트 close
connection.close();
// → DB 에 종료 알림
// → 세션 해제
// → TCP 4-way handshake

7.3 idle 타임아웃

idle 타임아웃:

  세션 일정 시간 미사용:
    - 자동 종료
    - 자원 회수

  MySQL: wait_timeout (기본 8시간)
  HikariCP: idle-timeout (10분)

  → 양쪽 시간 조율 필요

7.4 강제 종료

-- DB 관리자 강제 종료 (MySQL)
SHOW PROCESSLIST;   -- 세션 목록
KILL 12;            -- 세션 ID 12 종료

-- PostgreSQL
SELECT pg_terminate_backend(pid);

7.5 종료 시 정리

종료 시 정리:

  세션 종료:
    - 미완료 트랜잭션 rollback
    - 메모리 해제
    - 잠금 해제 (lock)
    - 임시 데이터 정리

7.6 ILIC 의 맥락

-- 세션 종료 사례 (ILIC)

-- 1. 평소: HikariCP 가 close (풀로 반환, 세션 유지)

-- 2. idle 타임아웃:
--    HikariCP idle-timeout (10분) 보다
--    MySQL wait_timeout (28800 = 8시간) 길어야
--    → 안 그러면 끊긴 Connection 사용 위험

-- 3. 운영 도구로 확인
SHOW PROCESSLIST;
-- ID  User       Time  Command
-- 12  ilic_user  3600  Sleep    ← 1시간 idle
-- 13  ilic_user  0     Query

-- 4. 문제 세션 강제 종료 (운영자)
KILL 12;

-- 5. 애플리케이션 재시작 시
-- → HikariCP 가 모든 Connection close
-- → 세션 모두 해제

7.7 자기 점검 답변

세션 종료 방식은?

:
1. 종료:

  • close/타임아웃/강제
  1. close:

    • 클라이언트
  2. idle:

    • 자동
  3. 강제:

    • KILL (관리자)

8️⃣ DB 입장의 풀

8.1 DB 가 보는 풀

DB 가 보는 풀:

  애플리케이션 풀 X:
    - 그냥 N 개 클라이언트
    - 각자 세션
    - 누가 풀인지 모름

→ 풀은 클라이언트 개념

8.2 클라이언트 인지

클라이언트 인지:

  DB 측:
    - Connection 들 = 평범한 세션
    - HikariCP 알 필요 없음
    - 그저 N 개 사용자

→ 풀은 추상화 (DB 무관)

8.3 자원 관점

DB 자원 관점:

  세션 N 개:
    - 메모리 (N × 수 MB)
    - CPU (인증/캐시)
    - 파일 디스크립터

→ N 작을수록 DB 부담 ↓

8.4 운영 모니터링

-- DB 입장 모니터링 (MySQL)

-- 활성 세션
SHOW PROCESSLIST;

-- 세션 수
SELECT COUNT(*) FROM information_schema.processlist;

-- 활성/슬립 비율
SELECT command, COUNT(*) 
FROM information_schema.processlist 
GROUP BY command;

-- max_connections
SHOW VARIABLES LIKE 'max_connections';

8.5 ILIC 의 맥락

DB 입장 모니터링 (ILIC MySQL)

ILIC MySQL 모니터링:

  -- 현재 세션
  SHOW PROCESSLIST;
  → ilic_user 의 세션들 (HikariCP 풀)
    + 운영 도구 세션
    + 백그라운드

  -- 사용량
  SELECT 
    (SELECT COUNT(*) FROM information_schema.processlist) AS used,
    (SELECT @@max_connections) AS max,
    ROUND(
      (SELECT COUNT(*) FROM information_schema.processlist) 
      / @@max_connections * 100, 2
    ) AS pct;
  → 사용률 (예: 35 / 151 = 23%)

  → 풀 크기 조정 근거
  → max_connections 증설 시점

8.6 자기 점검 답변

DB 입장에서 풀이 어떻게 보이나?

:
1. DB 입장:

  • 풀 X, N 개 세션
  1. 인지:

    • 클라이언트 모름
  2. 자원:

    • N × 메모리
  3. 모니터링:

    • PROCESSLIST

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
연결 5단계?TCP/세션/SQL/트랜잭션/종료
DB 세션?DB 가 할당한 자원
세션 단위?트랜잭션
Connection-Session?1:1
한 Conn 두 TX?불가 (세션 1 TX)
풀 N = ?세션 N
종료?close/idle/KILL
DB 입장?N 개 세션
max_connections?DB 한계
풀과 세션 차이?클라/서버

9.2 자기 점검 체크리스트

5단계

  • TCP~종료

세션

  • 정의

트랜잭션 단위

  • 의미

1:1

  • 매핑

두 TX 불가

  • 이유

N=N

  • 풀=세션

종료

  • 방식

DB 입장

  • 풀 X

9.3 추가 심화 질문

Q1: PgBouncer?

답:

  • PostgreSQL 외부 풀
  • 미들웨어
  • 더 적은 DB 세션
  • statement-level 풀

Q2: 세션 vs 트랜잭션?

답:

  • 세션: 연결 단위 (계속)
  • 트랜잭션: 작업 단위 (commit 단위)
  • 세션 안에 여러 트랜잭션
  • 1:N

Q3: 트랜잭션 중 풀로 반환?

답:

  • 안 됨 (트랜잭션 진행 중)
  • commit/rollback 후 반환
  • @Transactional 끝까지

Q4: Connection 검증?

답:

  • 풀에서 빌릴 때 살아있나
  • validation query (SELECT 1)
  • HikariCP: 자동 검증
  • 끊긴 Connection 회피

Q5: max_connections 늘리기?

답:

  • DB 설정 (my.cnf)
  • 메모리 ↑
  • 운영체제 한계 (ulimit)
  • 무한정 X (자원)

🎯 핵심 요약 — 3줄 정리

1. 연결 5단계와 세션

  • TCP 연결 → 세션 생성 → SQL 실행 → 트랜잭션 종료 → 연결 종료
  • 세션 = DB 가 할당한 자원 (메모리/상태/트랜잭션 컨텍스트)

2. Connection ↔ Session 1:1

  • 한 Connection = 한 세션 (DB 측)
  • 한 세션은 한 번에 한 트랜잭션 → 한 Connection 두 트랜잭션 불가

3. 풀 N = 세션 N

  • 풀에 Connection 100개면 DB 에 세션 100개
  • max_connections 한계 고려 (풀 크기 + 다른 클라이언트)

📚 다음으로...

Unit 4.4 — DB Lock 개념 (Phase 4 완주)

이번 Unit에서 세션/연결을 봤다면, 다음은 DB Lock (Phase 4 마지막).

  • 락의 필요성 (원자성 보호)
  • 공유 락 (S) / 배타 락 (X)
  • 자바 synchronized 와 닮음 (4주차)
  • 데드락

Phase 4 진행 상황

🔗 Phase 4 — Connection Pool과 DB 세션
  ✅ Unit 4.1 매 요청마다 연결의 비효율
  ✅ Unit 4.2 Connection Pool 개념 ★깊이
  ✅ Unit 4.3 DB 세션과 연결 구조 ← 여기
  ⏭ Unit 4.4 DB Lock 개념 — Phase 4 완주

6주차 누적 진행

🧪 Part A (9 Unit) ✅
💾 Part B — DB 접근의 진화
  ✅ Phase 3 — JDBC (3)
  🔗 Phase 4 — Connection Pool (3/4)

총: 15/28 Unit
profile
Software Developer

0개의 댓글