"대부분의 상황에서 데이터 수정 중 충돌이 발생한다"라는 비관적 상황 가정
"대부분의 상황에서 데이터 수정 중 충돌이 발생하지 않는다"라는 낙관적 상황 가정
version 컬럼 (숫자 or Timestamp)를 두고 조회 및 업데이트에 적용| 구분 | 비관적 락 | 낙관적 락 |
|---|---|---|
| 기본 가정 | 충돌이 자주 발생 | 충돌이 드물게 발생 |
| 방식 | 미리 DB 락을 걸고 충돌을 차단 | 락 없이 진행 후 커밋 시 충돌 감지 |
| 구현 위치 | 주로 DB 수준(X-lock, S-lock 등) | 주로 애플리케이션 + 버전 컬럼 |
| 성능 | 동시성 낮고 지연 증가 가능 | 동시성 높지만 충돌 시 재시도 비용 발생 |
| 데드락 위험 | 상대적으로 높음 | 매우 낮음 |
| 적합한 사례 | 금융 거래, 재고 관리 등 | 게시글, 설정, 일반 업무 데이터 수정 등 |
-- 비관적 락
-- quantity가 10이라고 가정
BEGIN;
SELECT quantity FROM stock WHERE id = 1 FOR UPDATE; -- 락 획득
-- 잠시 대기 (재고 확인 로직)
UPDATE stock SET quantity = quantity - 1 WHERE id = 1; -- quantity=9
COMMIT; -- 락 해제
BEGIN;
SELECT quantity FROM stock WHERE id = 1 FOR UPDATE; -- 세션1 락으로 대기
-- 세션1 커밋 후 진행
UPDATE stock SET quantity = quantity - 1 WHERE id = 1; -- quantity=8
COMMIT;
-- 즉시 실패
SELECT quantity FROM stock WHERE id = 1 FOR UPDATE NOWAIT;
-- 5초 대기 후 실패
SELECT quantity FROM stock WHERE id = 1 FOR UPDATE WAIT 5;
-- 낙관적 락
CREATE TABLE posts (
post_id NUMBER PRIMARY KEY,
content VARCHAR2(1000),
version NUMBER DEFAULT 0 -- 버전 관리 컬럼
);
SELECT post_id,
content,
version
FROM posts
WHERE post_id = 1;
UPDATE posts
SET content = 'Modified Content',
version = version + 1 -- 성공 시 버전 업그레이드
WHERE post_id = 1
AND version = 5; -- 대상 버전 번호를 조건에 넣음
상황에 따라 무결성과 데드락 위험을 잘 고려하여
비관적 락과 낙관적 락을 적절히 사용하자💡