Server

[낙관적락/Optimistic Lock]_기본 개념 (비관적 락/PESSIMISTIC 짧은 설명 포함)

Raconer 2024. 2. 15. 00:39
728x90

동시성 제어 방식: 비관적 락 vs 낙관적 락

🔒 비관적 락 (Pessimistic Lock)

동시성 제어를 위한 가장 보편적인 방법
락을 통한 줄세우기

✅ 장점

  • 동시성 이슈를 DB에서 강제로 막기 때문에 안전함

❌ 단점

  • 락을 통한 동시성 제어는 불필요한 대기 상태를 만듦
  • 동시성이 빈번하지 않은 쿼리에도 락이 걸려 다른 쿼리가 대기 상태가 됨
  • 락 범위가 커질수록 성능 저하 발생 (Connection Pool 고갈 가능성)

💡 MySQL에서의 쓰기락 (Exclusive Lock) 예시

START TRANSACTION;

-- 특정 조건의 Row에 쓰기락을 건다
SELECT *
FROM post
WHERE member_id = 2
AND contents = 'v'
FOR UPDATE;

-- 작업이 끝난 후 커밋
COMMIT;

FOR UPDATE는 쓰기락을 의미하며, 락은 COMMIT 시점에 해제됨
performance_schema.data_locks를 통해 락 상태 확인 가능


🪄 낙관적 락 (Optimistic Lock)

동시성 이슈가 자주 발생하지 않길 기대하고, 애플리케이션 단에서 제어
데이터 충돌이 발생할 수 있으므로, 실패에 대한 처리를 명시적으로 구현해야 함

✅ 장점

  • 락을 걸지 않기 때문에 성능이 좋음
  • 동시성이 낮은 환경에 적합

❌ 단점

  • 충돌 발생 시 재시도 로직 또는 예외 처리를 개발자가 직접 구현해야 함

🔁 핵심 개념: CAS (Compare And Set)

조건: 특정 버전에서만 갱신 허용 → 충돌 방지


🧪 예제: 낙관적 락 시나리오

이름 잔액 버전
홍길동 1000원 1
  1. 트랜잭션_1: SELECT * FROM account WHERE name = '홍길동' → (잔액: 1000, 버전: 1)
  2. 트랜잭션_2: SELECT * FROM account WHERE name = '홍길동' → (잔액: 1000, 버전: 1)
  3. 트랜잭션_1: UPDATE account SET 잔액 = 900, 버전 = 2 WHERE name = '홍길동' AND 버전 = 1 → ✅ 성공
  4. 트랜잭션_2: UPDATE account SET 잔액 = 900, 버전 = 2 WHERE name = '홍길동' AND 버전 = 1 → ❌ 실패 (버전 불일치)

💡 처리 방식 예

  • 재시도 로직
  • 사용자에게 알림
  • 충돌 무시

✅ 정리 비교

항목 비관적 락 낙관적 락
방식 DB 락 이용 (FOR UPDATE 등) 애플리케이션 단에서 버전 비교
성능 낮음 (동시성 많을수록 대기 발생) 높음 (락 없음, 대신 실패 대비 필요)
동시성 강도 높음 (DB가 직접 충돌 방지) 낮음 (충돌 발생 가능성 존재)
충돌 처리 자동 (DB가 막음) 수동 (코드에서 재시도 등 구현 필요)
728x90

'Server' 카테고리의 다른 글

Session 이란?  (0) 2024.02.24
동시성 제어  (0) 2024.02.18
[비관적인락/PESSIMISTIC]_쓰기락 테스트  (0) 2024.02.06
[비관적인락/PESSIMISTIC]_쓰기락과 읽기락  (0) 2024.02.06
[디자인 패턴] 추상 팩토리 패턴  (0) 2024.02.03