728x90
동시성 제어를 위한 가장 보편적인 방법
락(Lock)을 통한 순차 실행 제어는 동시성 이슈를 해결하는 가장 기본적이고 보편적인 방식입니다.
중요 ✅ 1: 락의 범위는 최소화해야 한다
- 락이 걸린 동안 다른 트랜잭션은 대기 상태가 되므로, 락 범위가 넓으면 시스템 전체 성능이 저하됩니다.
- 심한 경우 단일 스레드처럼 직렬 처리되는 상황이 발생할 수 있습니다.
- 특히 Connection Pool을 사용하는 경우 락이 길어지면 풀 고갈로 인해 새로운 요청 자체가 블로킹됩니다.
MySQL에서 락의 범위를 줄이는 방법
MySQL은 트랜잭션의 종료 시점(커밋/롤백)에 락이 해제됩니다.
따라서 트랜잭션의 길이 = 락의 유지 시간 입니다.
트랜잭션 범위를 최소화하면 락 범위도 자연스럽게 줄어듭니다.
예시: S3 업로드 같은 외부 작업은 트랜잭션 밖에서 실행하는 것이 좋습니다.
// Bad: 트랜잭션 안에서 S3 업로드 @Transactional fun upload() { saveToDatabase() uploadToS3() // 외부 API → 락이 길어짐 } // Good: 트랜잭션 안에는 DB 처리만 fun upload() { saveToDatabase() uploadToS3() // 트랜잭션 바깥에서 실행 }
MySQL의 락 종류: 읽기락 vs 쓰기락
읽기락 (Shared Lock) | 쓰기락 (Exclusive Lock) | |
---|---|---|
읽기 요청 | 가능 (공유 가능) | 대기 |
쓰기 요청 | 대기 | 대기 |
1. 읽기락 (Shared Lock)
- 여러 트랜잭션이 동시에 읽기만 수행할 수 있음
- 명령어:
SELECT * FROM your_table WHERE condition FOR SHARE;
2. 쓰기락 (Exclusive Lock)
- 쓰기 작업은 단독으로만 수행 가능
- 읽기/쓰기 모두 대기시킴
- 명령어:
SELECT * FROM your_table WHERE condition FOR UPDATE; UPDATE your_table SET col = val WHERE condition; DELETE FROM your_table WHERE condition;
일반
SELECT
는 락이 없는 Consistent Read로 처리되며, 성능에 영향을 주지 않습니다.
참고: MySQL Consistent Nonlocking Reads
중요 ✅ 2: 락의 범위 종류
MySQL에서는 락이 걸리는 범위에 따라 다양한 락 종류가 존재합니다.
- 테이블 락: 테이블 전체에 락을 겁니다 (MyISAM, 명시적 테이블 락 등)
- 레코드 락(Row Lock): 특정 ROW에 락을 거는 방식 (일반적으로 가장 중요)
- MySQL InnoDB는 실제로 레코드가 아니라 인덱스에 락을 겁니다
- WHERE 절에 인덱스가 없으면, 불필요한 범위까지 락이 걸릴 수 있습니다
- 갭 락(Gap Lock): 두 ROW 사이의 공간(갭)에 락을 거는 방식
- 팬텀 리드 방지용으로 사용됨 (Repeatable Read 격리 수준 이상에서 발생)
요약
- 락은 데이터 정합성을 보장하는 핵심 수단이지만, 성능 저하의 원인이 될 수 있음
- MySQL에서 트랜잭션 길이 = 락 유지 시간이므로, 외부 API 호출 등은 트랜잭션 밖으로 분리
- WHERE 조건에 인덱스가 없으면 예상보다 더 넓은 범위에 락이 걸릴 수 있음
- 갭락 등은 격리 수준과 관련이 있으며, 고급 트랜잭션 제어에 유의해야 함
728x90
'Server' 카테고리의 다른 글
[낙관적락/Optimistic Lock]_기본 개념 (비관적 락/PESSIMISTIC 짧은 설명 포함) (0) | 2024.02.15 |
---|---|
[비관적인락/PESSIMISTIC]_쓰기락 테스트 (0) | 2024.02.06 |
[디자인 패턴] 추상 팩토리 패턴 (0) | 2024.02.03 |
CAP 이론 (Consistency, Availability, Partition Tolerance) (0) | 2024.02.03 |
낙관적인락(Optimistic Locking) / 비관적인(Pessimistic Locking) (0) | 2023.08.09 |