비행기 예약 서비스에서 두 사람이 동시에 같은 좌석을 예약한다거나, 온라인 쇼핑몰에서 수량이 1개 남은 상품을 두 사람이 동시에 결제하게 된다면 어떻게 될까?
이처럼 우리가 사용하는 서비스에서 빈번하게 마주할 수 있는 문제를 '동시성 문제'라고 한다. 이러한 상황이 발생하지 않도록 사전에 처리가 필요하다.
동시성 제어를 위한 두 가지 접근법으로 비관적 락(Pessimistic Lock)과 낙관적 락(Optimistic Lock)이 있다.
비관적 락(Pessimistic Lock)
비관적 락은 '충돌이 자주 발생할 것이다'라는 비관적인 가정에 기반한 제어 방식이다. 데이터에 잠금을 설정해서 다른 사용자가 같은 데이터에 접근할 수 없도록 차단하는 것이다.
원리
1. 데이터를 읽거나 수정하기 전에 데이터에 락(Lock)을 설정한다.
2. 락이 설정된 데이터는 다른 곳에서 접근할 수 없다.
3. 작업이 완료되면 락을 해제한다.
낙관적 락(Optimistic Lock)
낙관적 락은 '충돌이 자주 발생하지 않을 것이다'라는 낙관적인 가정에 기반한 제어 방식이다. 데이터에 잠금을 설정하지 않고, 데이터 변경 시점에 충돌 여부를 확인한다.
원리
1. 데이터를 읽을 때 현재 상태를 나타내는 version 값을 가져온다.
2. 데이터를 수정할 때 저장 시점의 version과 데이터베이스의 version이 동일한지 확인한다.
3. 값이 일치하면 version을 증가시켜 업데이트 한다.
4. 값이 다르면 작업을 중단하거나 재시도한다.
결론
낙관적 락은 락을 설정하고 해제하는 과정이 없기 때문에 비관적 락 방식보다 자원의 소모가 적고 빠르게 실행된다. 하지만 충돌이 자주 발생하는 상황에서는 무의미한 실행과 재시도 로직 등으로 인하여 성능이 더 안좋을 수가 있다.
낙관적 락이 적합한 경우
- 읽기 작업이 많은 환경: 데이터 충돌이 드문 시스템
- 분산 시스템: 데드락 방지가 중요한 경우
- 사용자 데이터: 개인화된 데이터를 처리하며 충돌 가능성이 낮은 애플리케이션
비관적 락이 적합한 경우
- 충돌이 빈번한 환경: 동시에 데이터에 접근하는 트랜잭션이 많은 경우
- 데이터 무결성이 중요한 작업: 단일 작업 실패가 치명적인 영향을 미치는 경우
- 실시간 처리: 즉시 결과가 필요한 작업으로 재시도 로직을 피해야 하는 경우
상황에 맞게 적절한 방법을 선택하는 것이 중요하다.
'Database' 카테고리의 다른 글
| Merge Join vs Nested Loop Join (0) | 2024.03.25 |
|---|---|
| 쿼리 최적화 (0) | 2024.03.14 |
| MySQL(15) - 실행 계획 (0) | 2024.03.06 |
| MySQL(14) - 쿼리 힌트 (0) | 2024.02.29 |
| MySQL(13) - 옵티마이저 (0) | 2024.02.26 |