Notion에서 작성 된 글입니다. 템플릿이 깨진다면 Notion을 확인해주세요.
Lock | Notion
들어가기앞서…
hail-buttercup-c86.notion.site
들어가기앞서…
필자는 이번 프로젝트에서 이벤트 기능을 맡게되었다.
이벤트 기능의 주요 서비스는, 여러명의 사용자가 포인트를 지불하고 이벤트에 참여하면 이벤트에 누적 금액이 쌓이게되고, 목표 금액에 달성한 사용자만이 티켓을 얻게되는 이벤트이다.
때문에 이벤트 응모 요청은 동시에 여러명이 요청할 수 있는 API이다.
이런 사용자의 요청이 모두 다 정상적으로 반영되면 좋겠지만, 실제로는 동시에 여러명이 요청을 할 경우, 누적금액이 모두 정상적으로 반영이 될까? 결과부터 말해보자면 그렇지않다. 이런 동시성 문제를 해결하기 위해서는 Lock에 대한 기본적인 이해도가 필요하다. 이번 기회에 공부하며 알아보도록하자.
Lock
락은 트랜잭션 처리의 순차성을 보장하기 위한 방법이다. (트랜잭션이란 DB에서 나누어지지않는 가장 최소의 처리 단위이다.) 데이터의 일관성과 무결성을 지키기 위해 사용한다.
데이터베이스는 데이터를 영속적으로 저장하고있는 시스템이다. 이런 데이터베이스 시스템은 동시에 여러 사용자가 접근하는 상황을 피할수가 없는데, 이렇게 여러 사용자가 동시에 접근하게 되면 갱손 손실, 더티 리드, 불일치 읽기, 팬텀 리드등 다양한 문제가 발생한다. 이런 문제를 해결하기 위해 Lock을 사용하여 트랜잭션의 순차성을 보장한다.
Lock 종류
공유 락(Shared Lock: S Lock)
공유락은 읽기 명령에 대해 주어지는 Rock이다. 앞글자를 따와서 주로 S Lock로 표기된다.
공유락은 여러 사용자가 동시에 접근해도 문제가 없어, 공유락끼리의 동시 접근을 허용한다. 하지만 공유락이 설정된 데이터에 베타 락을 사용할 순 없다.
베타 락(Exclusive Lock)
베타 락은 쓰기 명령에 대해 주어지는 Rock이다. 앞글자를 따와서 주로 X Lock으로 표기된다.
공유 락은 여러 사용자가 동시에 접근해도 문제가 없는 반면에, 베타 락은 Lock이 걸린 대상을 제외한 다른 트랜잭션은 모두 읽기도, 쓰기도 막히게 된다.
업데이트 락(Update Lock)
업데이트 락은 수정을 위해 베타 락을 걸기 전에 COnversion Deadlock을 방지하기 위해 사용하는 락이다.
UPDATE 쿼리의 WHERE절에서 읽기가 발생하고, 그 후에 쓰기 과정이 발생하는데 이 과정에서 데드락이 발생할 수 있다.
만약 A와 B가 있다고 가정할 때, 동시에 UPDATE를 한다면, 서로 읽기과정에서 공유 락을 얻게 된다. 이후 베타락으로 전환하기
위해 데이터A와 데이터 B가 있다고 해보자.
베타락은 1개의 리소스만 접근할 수 있기때문에, 이미 다른 세션이 공유락을 잡고 있으면 대기하게 된다.
사용자1: 데이터A 공유락 → 데이터B를 수정하기위해 배타락 필요
사용자2: 데이터B 공유락 → 데이터A를 수정하기위해 배타락 필요
- A는 B가 데이터B 락을 풀어줘야 진행 가능 → B를 기다림
- B는 A가 데이터A 락을 풀어줘야 진행 가능 → A를 기다림
두 세션이 동시에 UPDATE 쿼리를 던져서 서로 읽기 과정에서 공유 락을 얻고 베타 락으로 전환하려고 할 때 서로가 가지고 있는 공유 락이 잡힌 데이터로 접근하려고 한다고 생각하면 공유 락 때문에 데드락이 발생할 수 있다.
내재 락(Intent Lock)
내재 락은 사용자가 요청한 범위에 락을 걸 수 있는지에 대한 유무를 파악하기 위해 사용하는 락이다. 공유 락과 베타 락 앞에 I 기호를 붙여서 IS, IX, SIX 등으로 표현된다.
A 테이블의 로우에 대해서 락이 걸려있는 경우, 다른 세션에서 A 테이블 전체에 대한 락을 걸기 원한다면 로우에 대한 락이 끝날 떄까지 기다려야 한다.
마무리하며..
이번 프로젝트를 통해 단순히 기능을 만드는 것에서 그치지 않고, 동시에 수많은 요청이 몰리는 환경에서 데이터를 안전하게 지키는 방법까지 고민하게 되었습니다.
처음에는 “DB가 알아서 처리해주겠지”라고 생각했지만, 실제로는 락(Lock)을 이해하고 트랜잭션을 설계하지 않으면 금액 누락이나 중복 처리 같은 문제가 쉽게 발생한다는 것을 직접 경험했습니다.
이 과정을 통해 락의 종류와 동작 원리를 공부하며, 동시성 제어가 서비스 안정성을 좌우한다는 사실을 몸소 배울 수 있었고, 앞으로의 개발에서도 중요한 기준이 될 것 같습니다.
'CS' 카테고리의 다른 글
[ CS ] 동기와 비동기 (0) | 2025.09.18 |
---|---|
[CS] 캐시 메모리(Cache Memory)란? (1) | 2025.06.20 |