반응형
이 글은 실서비스 운영 중 발생한 커넥션 풀 이슈를 바탕으로, HikariCP + Spring + MyBatis 환경에서 커넥션 풀이 어떻게 동작하는지, 어떤 설정이 실제로 의미가 있는지 정리한 글이다.
1. 커넥션 풀이 부족해지는 대표적인 원인
실무에서 커넥션 풀 이슈의 원인은 거의 정해져 있다.
- 커넥션 반환 누락 (close 안 됨)
- 트랜잭션 범위가 과도하게 큼
- 오래 걸리는 쿼리로 커넥션 점유 시간이 김
- 풀 사이즈를 DB 한계보다 크게 설정
중요한 점은 "풀 크기가 작아서" 발생하는 경우는 생각보다 적다는 것이다.
2. SqlSessionTemplate를 쓰고 있다면
@Primary
@Bean
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("node01SessionFactory") SqlSessionFactory ssf) {
return new SqlSessionTemplate(ssf);
}
이 구조는 Spring + MyBatis의 정석적인 구성이다.
- SqlSessionTemplate이 내부적으로 커넥션을 획득/반환
- 개발자가 openSession() / close()를 직접 호출하지 않음
- 정상 구조라면 커넥션 누수가 발생하기 어렵다
따라서 이 환경에서 Connection is not available 에러가 난다면, 원인은 거의 항상 트랜잭션 길이, 쿼리 지연, DB 세션 한계 쪽이다.
3. commit과 커넥션 반환은 전혀 다른 개념
자주 헷갈리는 부분이다.
- commit: 데이터 변경 확정
- connection return(close): 커넥션을 풀로 돌려보냄
중요한 사실:
commit을 안 해도, 트랜잭션이 끝나면 커넥션은 반환된다.
Spring의 @Transactional이나 SqlSessionTemplate 환경에서는
- commit → 성공 시
- rollback → 실패 시
어느 경우든 메서드 종료 시 커넥션은 풀로 반환된다.
즉, 커넥션 부족 문제는 commit 누락 문제가 아니다.
4. HikariCP 주요 설정 정리
4.1 maximumPoolSize
- 풀에서 가질 수 있는 최대 커넥션 수
- 실제 사용량과 반드시 일치하지 않음
실제 사례:
- maximumPoolSize = 300
- activeConnections 최대 = 11
→ 풀을 과도하게 크게 잡은 상태
권장 접근:
- 실제 동시 DB 요청 수 기준으로 설정
- 대부분 서비스는 30~50 수준이면 충분
4.2 connection-timeout
- 풀에서 커넥션을 못 구했을 때 기다리는 최대 시간
- 기본값: 30초 (30000ms)
동작 방식:
- 커넥션 없음 → 최대 30초 대기
- 30초 초과 → Connection is not available 예외 발생
너무 길면:
- 쓰레드가 오래 블로킹됨
너무 짧으면:
- 순간 트래픽에도 바로 장애
4.3 maxLifetime
로그에서 자주 보이는 메시지:
connection has passed maxLifetime
의미:
- 설정된 수명을 초과한 커넥션을 정상적으로 폐기하고 재생성
- 기본값: 30분
문제가 아니라 풀 안정성을 위한 정상 동작 로그다.
5. 풀 통계 로그는 항상 남지 않는다
- HikariCP는 기본적으로 풀 상태 로그를 남기지 않음
- 로그 레벨을 올려야 확인 가능
logging.level.com.zaxxer.hikari=DEBUG
또는 JMX를 통해 다음 지표 확인 가능:
- activeConnections
- idleConnections
- totalConnections
- threadsAwaitingConnection
6. 오라클 / MSSQL에서의 락과 커넥션 점유
Oracle
- 행 단위 비관적 락: SELECT ... FOR UPDATE
- 논리적 락: DBMS_LOCK
DBMS_LOCK.REQUEST(...)
MSSQL
- 행 락: WITH (UPDLOCK)
- 테이블 락: TABLOCK, TABLOCKX
- 논리적 애플리케이션 락: sp_getapplock
EXEC sp_getapplock @Resource='ORDER_123', @LockMode='Exclusive'
이런 락들은 트랜잭션이 길어질수록 커넥션 점유 시간을 늘린다.
7. 핵심 결론
- 커넥션 부족은 대부분 풀 크기 문제가 아니다
- commit 여부와 커넥션 반환은 무관
- SqlSessionTemplate 사용 시 누수 가능성은 낮음
- 실제 봐야 할 것은:
- 트랜잭션 길이
- 쿼리 실행 시간
- DB 세션 제한
- 순간 동시 요청 패턴
커넥션 풀 문제는 설정을 키워서 해결되지 않는다. 관측 → 이해 → 줄이기가 정답이다.
반응형
'IT' 카테고리의 다른 글
| 커넥션 타임아웃과 리드 타임아웃 (0) | 2026.01.13 |
|---|---|
| 실행계획과 인덱스 (0) | 2025.12.16 |
| Business Exception vs System Exception (0) | 2025.12.15 |
| Spring @ControllerAdvice 완전 정리 (0) | 2025.12.15 |
| Spring @Transactional Propagation 완전 정리 (0) | 2025.12.15 |
댓글