Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- Java
- Algospot
- sorting
- Python
- JavaScript
- 따라하며 배우는 C언어
- 따라하면서 배우는 C언어
- web
- BFS
- BASIC
- String
- Cleancode
- server
- DP
- 생활코딩
- php
- Algorithm
- 따배씨
- 종만북
- Math
- graph
- C
- BOJ
- 정수론
- 백준
- dfs
- C언어
- greedy
- udemy
- 인프런
Archives
- Today
- Total
몽상실현개발주의
단순 조회에도 트랜잭션을 쓰면 문제가 될까? 본문
데이터베이스를 쓰다 보면 “조회 요청에도 트랜잭션을 열어도 괜찮을까?”라는 질문이 자주 나옵니다. 특히 스프링 같은 프레임워크는 `@Transactional`을 쉽게 붙일 수 있어서, 무심코 모든 요청을 트랜잭션으로 감싸는 경우도 많죠.
결론부터 말하면:
👉 단순 SELECT 한 번만 하고 바로 끝낸다면 큰 문제는 없다.
👉 하지만 트랜잭션을 오래 열어두면 락보다 커넥션·Undo Log 유지가 문제가 된다.
1. Undo Log란 무엇인가?
- InnoDB 같은 엔진은 `UPDATE/DELETE/INSERT`를 할 때 기존 데이터를 Undo Log 에 기록합니다.
- 이유는 MVCC(다중 버전 동시성 제어) 때문입니다.
- 어떤 트랜잭션은 최신 데이터를 보지만,
- 아직 끝나지 않은 다른 트랜잭션은 시작 당시의 데이터 를 그대로 볼 수 있어야 합니다.
- 이 “옛날 버전”을 재구성하는 재료가 Undo Log입니다.
👉 즉, Undo Log는 “쓰기 작업”이 있을 때 생성 됩니다.
2. 단순 SELECT에서 Undo Log는?
- 단순 조회만 하는 트랜잭션은 Undo Log를 직접 만들진 않습니다.
- 하지만 문제가 되는 건 “Undo Log를 지우지 못하는 상황”입니다.
예시:
세션 A: BEGIN;
세션 A: SELECT * FROM emp WHERE id=1; -- 홍길동 조회
세션 B: UPDATE emp SET name='김철수' WHERE id=1; -- Undo Log에 '홍길동' 저장
COMMIT;
세션 A: SELECT * FROM emp WHERE id=1; -- 여전히 '홍길동'을 보여줘야 함
세션 A가 트랜잭션을 끝내지 않았기 때문에, DB는 Undo Log를 계속 들고 있어야 합니다.
👉 트랜잭션이 길어질수록 Undo Log가 쌓이고 Purge(정리)가 지연됩니다.
👉 결국 디스크 공간 증가, 메모리 압박, 성능 저하 로 이어집니다.
3. “락을 거는 SELECT”는 또 다르다
- `SELECT ... FOR UPDATE` → 읽은 행에 배타 락(X Lock)
- `SELECT ... FOR SHARE` → 읽은 행에 공유 락(S Lock)
- 이 경우에는 Undo Log 문제가 아니라 락이 걸린 채로 트랜잭션이 끝날 때까지 다른 세션을 막는 것 이 위험 요소입니다.
- 인덱스 설계가 잘못되면 범위 전체에 락이 걸려 사실상 테이블 락처럼 동작하기도 합니다.
4. 결국 문제는 “트랜잭션의 길이”
- 단순 SELECT라도 트랜잭션을 오래 열어두면 → Undo Log 유지 부담 발생
- Locking SELECT(`FOR UPDATE`)라면 → 그 락이 오래 유지되어 다른 세션을 블로킹
- 게다가, 트랜잭션이 열려 있다는 건 커넥션 풀 리소스를 계속 점유한다는 의미이기도 합니다.
5. 실무에서의 안전한 패턴
- 읽기 전용 API
- 트랜잭션 안 쓰거나, 꼭 필요하다면 `@Transactional(readOnly = true)`로 짧게.
- 쓰기 API
- 꼭 필요한 로직만 묶어서 빠르게 커밋/롤백.
- 대량 조회
- 스트리밍 방식으로 오래 끌지 말고, 페이징/배치로 나눠서 처리.
- Locking SELECT
- 필요한 곳에서만, 짧게 사용.
마무리
👉 “한 번만 조회하고 바로 끝낸다”면 트랜잭션을 써도 Undo Log 문제는 거의 없습니다.
👉 하지만 트랜잭션을 괜히 오래 잡아두면, 락보다 커넥션 점유·Undo Log 유지가 더 큰 문제 가 됩니다.
정리:
- 단순 조회 = 락 없음, Undo Log 직접 생성 없음
- 긴 트랜잭션 = Undo Log 유지 + 커넥션 점유로 DB 성능 저하
- Locking SELECT = 진짜 락이 걸려 다른 세션 차단
“조회는 짧게, 쓰기는 빠르게” 이것이 안전한 DB 트랜잭션 운영의 기본 원칙입니다.
반응형
'Dev' 카테고리의 다른 글
| MyBatis는 왜 서비스 레이어가 뚱뚱해질 수밖에 없는가? : 1부 (0) | 2025.08.24 |
|---|---|
| CQRS: Command와 Query 분리란 무엇인가? (0) | 2025.08.24 |
| Java 컬렉션 프레임워크 인터페이스와 상속 관계 (0) | 2024.06.18 |
| 리플렉션과 Private : Java의 강력한 도구와 그 위험성 (0) | 2024.05.15 |
| Spring Boot에서 의존성 주입: @Bean과 @Autowired의 이해 (0) | 2024.05.06 |
Comments