내 잡다한 노트
DB에서 Lock 이란? 본문
Lock은 데이터베이스에서 **동시성 제어(Concurrency Control)**를 위해 사용하는 메커니즘으로, 여러 트랜잭션이 동일한 데이터에 동시에 접근하거나 수정하는 상황에서 데이터의 무결성과 일관성을 보장합니다.
1. Lock의 역할
데이터베이스에서 Lock은 다음과 같은 문제를 방지합니다:
- Dirty Read:
- 하나의 트랜잭션이 아직 커밋되지 않은 데이터를 읽는 문제.
- Lost Update:
- 두 트랜잭션이 동일 데이터를 수정하여 하나의 수정 내용이 덮어씌워지는 문제.
- Non-Repeatable Read:
- 동일 트랜잭션 내에서 같은 데이터를 두 번 읽었을 때 결과가 달라지는 문제.
- Phantom Read:
- 동일 트랜잭션 내에서 쿼리를 여러 번 실행했을 때, 새로운 행이 나타나거나 사라지는 문제.
Lock은 이러한 문제를 방지하여 데이터 무결성을 유지하고 트랜잭션 간 안전한 동시 실행을 보장합니다.
2. Lock의 종류
2.1 Lock의 범위에 따른 분류
- Row-Level Lock (행 단위 잠금)
- 데이터베이스의 특정 행(row)만 잠금.
- 동시성이 높음.
- 사용 예:
SELECT * FROM employees WHERE id = 1 FOR UPDATE; - 장점: 트랜잭션 간 충돌 가능성이 낮음.
- 단점: 잠금 관리 비용이 높아질 수 있음.
- Table-Level Lock (테이블 단위 잠금)
- 테이블 전체에 대해 읽기 또는 쓰기 작업을 제한.
- 사용 예:
LOCK TABLE employees IN WRITE MODE;
- 장점: 구현이 간단.
- 단점: 동시성이 낮아짐.
- Database-Level Lock (데이터베이스 단위 잠금)
- 데이터베이스 전체를 잠금.
- 일반적으로 백업 작업이나 데이터베이스 유지보수 시 사용.
- 사용 예: FLUSH TABLES WITH READ LOCK; (MySQL)
2.2 Lock의 유형에 따른 분류
- Shared Lock (공유 잠금, 읽기 잠금)
- 데이터를 읽는 동안 잠금이 걸리며, 다른 트랜잭션도 공유 잠금을 걸 수 있음.
- 데이터를 수정하려는 트랜잭션은 공유 잠금이 해제되길 기다려야 함.
- 사용 예:
SELECT * FROM employees LOCK IN SHARE MODE;
- Exclusive Lock (배타 잠금, 쓰기 잠금)
- 데이터를 수정할 때 사용되며, 해당 데이터에 다른 트랜잭션이 접근하지 못하게 함.
- 쓰기 작업 중 데이터 일관성을 보장.
- 사용 예:
SELECT * FROM employees WHERE id = 1 FOR UPDATE;
2.3 잠금 지속성에 따른 분류
- Pessimistic Lock (비관적 잠금)
- 데이터 충돌 가능성이 높은 환경에서 사용.
- 데이터에 접근 시 즉시 잠금을 걸어 충돌을 방지.
- 예:
SELECT * FROM employees WHERE id = 1 FOR UPDATE;
- Optimistic Lock (낙관적 잠금)
- 데이터 충돌 가능성이 낮은 환경에서 사용.
- 잠금을 사용하지 않고, 수정 시점에 데이터의 변경 여부를 확인.
- 일반적으로 버전 번호나 타임스탬프를 비교.
- 예: UPDATE employees SET salary = 5000 WHERE id = 1 AND version = 3;
3. Lock의 문제점
- Deadlock (교착 상태):
- 두 개 이상의 트랜잭션이 서로가 필요한 리소스를 잠그고 있어, 서로 대기 상태에 빠지는 현상.
- 해결 방법:
- 트랜잭션 타임아웃 설정.
- 잠금 순서 규칙 설정.
- Blocking (블로킹):
- 한 트랜잭션이 잠금을 소유하고 있을 때, 다른 트랜잭션이 대기하는 현상.
- 해결 방법:
- 트랜잭션 분리 수준을 낮추거나.
- 읽기 전용 작업에서 NOLOCK(또는 READ UNCOMMITTED)을 사용.
- Lock Escalation (잠금 확장):
- 행 단위 잠금이 많아지면, 데이터베이스가 성능을 위해 테이블 단위 잠금으로 자동 전환.
- 이로 인해 동시성이 크게 낮아질 수 있음.
4. Lock과 트랜잭션 격리 수준의 관계
SQL 표준은 트랜잭션 격리 수준을 정의하며, 격리 수준에 따라 Lock의 적용 범위가 달라집니다:
격리 수준Lock 적용 방식
Read Uncommitted | 잠금 사용 안 함 (Dirty Read 가능). |
Read Committed | 읽기 작업에 공유 잠금, 쓰기 작업에 배타 잠금. |
Repeatable Read | 읽기 작업에 공유 잠금, 업데이트된 데이터는 배타 잠금. |
Serializable | 모든 읽기/쓰기 작업에 배타 잠금(최고 수준 격리). |
'DB' 카테고리의 다른 글
DB와 관련된 기본 용어 (0) | 2025.01.27 |
---|---|
JDBC와 ODBC (0) | 2025.01.23 |
트랜잭션 (Transaction) (0) | 2025.01.21 |
Shard 란? (0) | 2025.01.21 |
Grouping 이란? (0) | 2025.01.21 |