낙관적 잠금과 비관적 잠금
SELECT ... FOR UPDATE(비관적 잠금)와 버전 열 / WHERE updated_at = ?(낙관적 잠금) 패턴을 비교해보세요.
낙관적 잠금과 비관적 잠금은(는) CoddyKit의 무료 SQL Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
두 가지 동시성 전략
- 비관적 방식 — 행을 읽을 때 잠그므로 다른 작업이 변경할 수 없음
- 낙관적 방식 — 잠그지 않고, 갱신할 때 행이 변경되지 않았는지 확인함
비관적 방식: SELECT ... FOR UPDATE
지금 잠그고 나중에 기록합니다:
BEGIN;
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
-- other transactions cannot lock or update this row
-- compute new balance...
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;FOR SHARE
읽기 잠금입니다. 다른 작업은 읽을 수 있지만 기록할 수는 없습니다:
SELECT * FROM orders WHERE id = 1 FOR SHARE;
-- others can SELECT FOR SHARE but cannot UPDATE비관적 방식의 장단점
장점: 이해하고 추적하기 쉬우며 재시도가 필요 없습니다.
단점: 동시성을 낮추고 잠금 대기와 교착 상태를 일으킬 수 있습니다.
낙관적 방식: 버전 열
버전과 함께 읽고, 예상한 버전과 일치하는지 WHERE version = expected로 확인하면서 기록합니다:
BEGIN;
SELECT id, balance, version FROM accounts WHERE id = 1;
-- compute new balance...
UPDATE accounts
SET balance = ?, version = version + 1
WHERE id = 1 AND version = ?;
-- check rows affected: 0 means someone else updated, retryupdated_at을 사용하는 낙관적 방식
명시적인 버전 열 대신 updated_at을 사용하는 동일한 방식입니다:
UPDATE accounts
SET balance = ?, updated_at = NOW()
WHERE id = ? AND updated_at = ?;
-- If updated_at has changed in the meantime, 0 rows affected — retry.낙관적 방식의 장단점
장점: 동시성이 높고 기다릴 필요가 없습니다.
단점: 기록이 실패하여 재시도 처리가 필요할 수 있으며, 충돌은 UPDATE 시점에야 드러납니다.
비관적 방식을 선택할 때
다음과 같은 경우에 사용합니다:
- 경합 행에 대한 경쟁이 높은 짧은 트랜잭션
- 금액 이체 — 작업이 부분적으로 처리되는 것을 방지해야 하는 경우
- 충돌 가능성이 높은 장시간 실행 작업
낙관적 방식을 선택할 때
다음과 같은 경우에 사용합니다:
- 충돌이 드문 읽기 중심 작업
- 요청 사이에 클라이언트가 행을 보유하는 상태 비저장 API
- 모바일 또는 오프라인에서 편집한 뒤 동기화하는 경우
하이브리드: FOR UPDATE NOWAIT
잠금을 시도하고, 이미 잠겨 있으면 즉시 실패시켜 사용자가 다시 시도하도록 합니다:
SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR if someone else holds it — user sees a friendly retry message자문 잠금
어떤 행에도 연결되지 않은 애플리케이션 수준의 잠금입니다:
SELECT pg_try_advisory_xact_lock(hashtext('order:42'));
-- True if you got the lock, false otherwise — useful for cross-row coordination.잠금 대상에 인덱스 추가를 잊지 마십시오
WHERE 열에 인덱스가 없는 FOR UPDATE는 예상보다 많은 행을 잠글 수 있습니다(일치하는 행만이 아니라 검색된 행을 잠급니다).
잠금 시간 제한
영원히 기다리지 않도록 lock_timeout을 설정하십시오:
SET lock_timeout = '5s';
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
-- ERROR if lock not acquired in 5 seconds복습
비관적 방식은 행을 잠그고, 낙관적 방식은 기록할 때 확인합니다.
- 비관적 방식: FOR UPDATE — 단순하지만 동시성을 낮춤
- 낙관적 방식: 버전 열 — 동시성이 높지만 재시도가 필요함
- 작업 특성에 따라 선택하고 필요하면 조합
빠른 확인
전자 상거래의 재고 차감 작업에서 경쟁이 매우 심합니다. 일반적으로 어떤 잠금 전략이 더 안전합니까?
자주 묻는 질문
“낙관적 잠금과 비관적 잠금” 강의는 무료인가요?
네 — “낙관적 잠금과 비관적 잠금” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Academy 강의 전체를 잠금 해제할 수 있습니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“낙관적 잠금과 비관적 잠금”에서 뭘 배우나요?
SELECT ... FOR UPDATE(비관적 잠금)와 버전 열 / WHERE updated_at = ?(낙관적 잠금) 패턴을 비교해보세요. 브라우저에서 직접 실행하는 실습 코드로 SQL Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
SQL Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 SQL Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“낙관적 잠금과 비관적 잠금” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 SQL Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 SQL Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.