반응형
Spring 기반 애플리케이션에서 MySQL과 트랜잭션을 다룰 때 종종 발생하는 문제가 있다.
바로 트랜잭션 전파(propagation) 방식에 따라 커넥션이 예상치 못하게 생성되거나 공유되지 않는 현상이다.
이 글에서는 전파 유형별 동작 원리와 실무에서 자주 발생하는 커넥션 이슈를 정리한다.

🔄 트랜잭션 전파(Propagation)란?
트랜잭션 전파는 메서드 호출 시 기존 트랜잭션이 있을 때의 처리 방식을 결정하는 속성이다.
Spring에서는 @Transactional(propagation = ...)으로 설정한다.
주요 전파 유형 요약
| 전파 유형 | 설명 |
| REQUIRED | 기존 트랜잭션이 있으면 참여, 없으면 새로 생성 (기본값) |
| REQUIRES_NEW | 항상 새 트랜잭션 시작. 기존 트랜잭션은 일시 정지 |
| NESTED | 기존 트랜잭션에 중첩되어 savepoint로 동작 |
| SUPPORTS | 있으면 참여, 없으면 트랜잭션 없이 실행 |
| NOT_SUPPORTED | 트랜잭션 없이 실행. 기존 트랜잭션은 정지 |
| MANDATORY | 반드시 트랜잭션 존재해야 실행 |
| NEVER | 트랜잭션이 있으면 예외 발생 |
반응형
⚠️ 전파 방식과 커넥션의 관계
Spring 트랜잭션은 커넥션과 밀접하게 연결되어 있다.
트랜잭션 범위 안에서 커넥션이 유지되며, 전파 방식에 따라 커넥션 공유 여부가 달라진다.
예시 1: REQUIRES_NEW는 새 커넥션 생성
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveAuditLog() {
// 별도 트랜잭션 → 별도 커넥션 사용
}
- 기존 커넥션은 중지되고, 새로운 커넥션이 풀에서 할당됨
- 동시에 여러 REQUIRES_NEW 호출 시 커넥션 풀이 고갈될 수 있음
예시 2: REQUIRED는 커넥션 공유
@Transactional
public void saveMainAndDetail() {
saveMain(); // REQUIRED
saveDetail(); // REQUIRED → 같은 커넥션
}
- 같은 트랜잭션 범위에서는 커넥션을 재사용
- 예외 발생 시 전체 롤백 처리 가능
🧪 실무 커넥션 이슈 시나리오
시나리오 1: 커넥션 풀 고갈
- 여러 서비스가 동시에 REQUIRES_NEW로 호출되면
- 커넥션을 계속 새로 빌려오게 되고
- Timeout waiting for connection 예외 발생
✅ 해결 방법
→ maximumPoolSize 증가 + 꼭 필요한 경우에만 REQUIRES_NEW 사용
시나리오 2: 트랜잭션 누락
- 서비스 A는 트랜잭션 O
- 서비스 B는 트랜잭션 없음
- 서비스 A → B 호출 시 B에서 DB 커넥션이 공유되지 않아 예외 발생 가능
✅ 해결 방법
→ 하위 서비스에도 @Transactional 명시하여 전파 가능하도록 설정
반응형
🔍 전파 방식 선택 가이드
| 상황 | 추천 전파 방식 | 이유 |
| 여러 저장 로직을 하나의 트랜잭션으로 묶을 때 |
REQUIRED | 커넥션 공유, 전체 롤백 가능 |
| 로깅, 알림 등 실패해도 되는 부가 작업 | REQUIRES_NEW | 메인 트랜잭션과 분리됨 |
| 내부 단계별 롤백을 나누고 싶을 때 | NESTED | savepoint 활용 가능 (단, MySQL은 JDBC 드라이버 지원 여부 확인) |
✅ 커넥션 절약을 위한 팁
- REQUIRES_NEW 남발 금지 → 불필요한 커넥션 증가
- NOT_SUPPORTED는 트랜잭션 격리 필요 없는 작업에만 사용
- 하나의 HTTP 요청 처리에서 커넥션 수가 늘어나는 구조는 지양
- 커넥션 풀 수치를 항상 전파 방식과 함께 고려
📘 공식 문서 참고
반응형
'DB' 카테고리의 다른 글
| [MySQL] 문자열 연결 함수: CONCAT, CONCAT_WS 활용법 (0) | 2025.07.19 |
|---|---|
| [MySQL] 문자열 길이 함수: LENGTH vs CHAR_LENGTH 정리 (3) | 2025.07.19 |
| [MySQL] (연결최적화6️⃣) 실무 연결 설정 체크리스트 총정리 (1) | 2025.07.19 |
| [MySQL] (연결최적화5️⃣) 커넥션 누수 원인 진단과 해결 전략 (1) | 2025.07.18 |
| [MySQL] (연결최적화3️⃣) 커넥션 타임아웃 설정과 오류 해결법 (0) | 2025.07.18 |
| [MySQL] (연결최적화2️⃣) 커넥션 풀의 개념과 실무 설정 가이드 (0) | 2025.07.18 |
| [MySQL] (연결최적화1️⃣) JDBC 드라이버 설정 핵심 옵션 정리 (0) | 2025.07.18 |
| [MySQL] (GIS6️⃣) 실무에서 자주 쓰는 공간 쿼리 예제 모음 (0) | 2025.07.18 |