근본없는 코딩
데이터베이스 Lock 본문
1. Lock ?
- 여러 Connection이 데이터를 수정하고자 할 때, 데이터의 일관성 문제가 발생할 수 있다.
- 이 문제를 해결하는 방법 중 1가지가 바로 Lock
- 내가 데이터를 Lock을 걸면 다른 Connection들은 이 데이터를 수정할 수 없다!
2. Lock과 Transaction
- Lock (동시성 제어) / 트랜잭션 (All or Nothing → 작업의 원자성 보장)
- Lock: 동시에 발생하는 수정 요청에 대한 데이터 일관성을 지키기 위한 메커니즘
- 트랜잭션 격리 수준: 여러 트랜잭션에 대해 각 트랜잭션들을 어떻게 처리할지에 대한 전략
※ Lock의 단위
3. 잠금이 필요한 이유?
- 동시성 제어: 트랜잭션들이 동시에 수행될 때, 일관성을 해치지 않도록 데이터 접근을 제어하는 DBMS의 기능
4. 동시성 제어는 어떻게 할까?
- 낙관적 Lock: App 내에서 버전을 통해 Lock을 구현할 수 있다
- 비관적 Lock: 충돌날 걸 예상하고 바로 Lock 걸어버림
4-1. 낙관적 잠금 (Optimisstic Lock)
- 데이터 갱신 시 경합이 발생하지 않을 것이라고 가정
- 한 사용자가 업데이트를 완료하면, 동시 업데이트 확약을 시도하는 다른 사용자들에게 충돌이 있음을 알림
→ 동시 업데이트가 거의 없는 경우 사용
4-2. 비관적 잠금 (Pessimistic Lock)
- 동일한 데이터를 동시에 수정 할 가능성이 높다라고 봄
- 다른 사용자는 먼저 시도한 사용자가 변경을 확약해서 레코드 잠금을 릴리즈할 때까지 대기해야 함.
→ 동시 업데이트가 빈번한 경우나 외부 시스템과 연동한 경우 사용
4-3. 비관적 Lock 연산의 종류
① 공용(Shared) Lock
- read 연산 실행 가능, write 연산 실행 불가능
- 데이터에 대한 사용권을 여러 트랜잭션이 함께 가질 수 있음
② 배타(Exclusive) Lock
- read 연산과 write 연산을 모두 실행 가능
- 배타 lock 연산을 실행한 트랜잭션만 해당 데이터에 대한 독점권을 가짐
5. Lock의 문제점
5-1. Blocking
- Lock들의 경합이 발생하여 특정 세션이 작업을 진행하지 못하고 멈춰 선 상태
→ 데이터에 대해 하나의 트랜잭션이 베타 lock을 걸면 다른 트랜잭션들은 어떠한 lock도 걸지 못하고 대기해야하기 때문
- 블로킹이 풀리는 시점은? 트랜잭션이 commit 혹은 rollback을 할 때
✨ 해결 방안?
① 트랜잭션을 짧게 정의
② 같은 데이터를 갱신하는 트랜잭션이 동시에 수행되지 않도록 설계
③ Lock Timeout을 이용하여 잠금 해제 시간을 조절
5-2. DeadLock 교착상태
- Dead Lock은 트랜잭션 간의 교착상태를 의미하며, Blocking 보다 심각한 교착상태
- 두 트랜잭션이 각각 Lock을 설정하고, 서로의 Lock에 접근하여 값을 얻어오려고 할 때, 서로의 Lock으로 인해 양쪽 트랜잭션이 영원히 처리되지 않는 상태
- 상대방 Lock이 끝나야 원하는 데이터를 가져오는데 바라보고 있는 서로의 Lock이 같은 상태가 되다보니 영원히 끝나지 않는 상황이 발생
✨ 해결 방안?
Oracle의 경우, Dead Lock을 감지하면 한쪽 Transactiond을 풀어버린다.
Transaction A의 마지막 Update 내용에 오류가 발생되고 Commit을 먼저 하도록 유도한다.
Transaction B는 아직 Wating 상태로 남아있고, Transaction A의 Commit을 기다리게 된다.
'✔ Database' 카테고리의 다른 글
Oracle SGA/Latch(+LOCK?) (1) | 2023.11.13 |
---|---|
[ORACLE] 트리거(Trigger) (0) | 2023.06.26 |