반응형
매일메일을 통해
하루하루 CS 공부하기
앞서 배운 내용에서 MVCC 동시성 제어 방식에서 Gap Lock과 Next-Key Lock을 통해 Phantom Read를 방지할 수 있다고 배웠었다.
그렇다면, 각 Lock과 Phantom Read란 무엇일까?
제대로 파헤쳐보자
Phantom Read란 무엇인가
트랜잭션이 동일한 조건의 쿼리를 반복 실행할 때, 나중에 실행된 쿼리에서 처음에는 존재하지 않았던 새로운 행이 나타나는 현상.
읽기 일관성을 유지하는 과정에서 발생할 수 있는 문제로, 데이터의 삽입/삭제가 다른 트랜잭션에 의해 이루어질 때 발생함.
-- 트랜잭션 A 시작
START TRANSACTION;
-- 트랜잭션 A 첫 번째 조회
SELECT * FROM orders WHERE amount > 150;
-- 트랜잭션 B 시작
START TRANSACTION;
-- 트랜잭션 B 새로운 행 삽입
INSERT INTO orders (customer_id, amount) VALUES (4, 250);
-- 트랜잭션 B 커밋
COMMIT;
-- 동일한 조건으로 트랜잭션 A 두 번째 조회시, 트랜잭션 A의 첫 번째 조회에는 존재하지 않던,
-- 트랜잭션 B에서 삽입된 새로운 행이 함께 조회됨
SELECT * FROM orders WHERE amount > 150;
Gap Lock 이란?
특정 인덱스 사이의 공간을 잠그는 락
기존 레코드 간의 간격을 보호하며, 새로운 레코드의 삽입을 방지한다.
범위 내에 특정 레코드가 존재하지 않을 때 적용된다.
트랜잭션이 특정 범위 내에서 데이터 삽입을 막아, Phantom Read 현상을 방지한다.
예를 들어, 인덱스 값 10과 20 사이의 Gap Lock을 걸면 이 범위 내에 새로운 레코드 15를 추가할 수 없다.
-- id 1, 3, 5가 저장된 orders 테이블
-- 트랜잭션 A 시작
START TRANSACTION;
-- 트랜잭션 A 1-3과 3-5 사이의 갭과 3 레코드 락 설정(넥스트키 락)
SELECT * FROM orders WHERE orders_id BETWEEN 2 AND 4 FOR UPDATE;
-- 트랜잭션 B 시작
START TRANSACTION;
-- 트랜잭션 B가 id 4에 데이터 삽입 시도 시, 갭락으로 인해 삽입이 차단되어 대기
INSERT INTO orders (orders_id, orders_amount) VALUES (4, 200);
...
Next-Key Lock이란?
Record Lock + Gap Lock
특정 인덱스 레코드와 그 주변의 Gap을 동시에 잠그는 락.
특정 레코드 자체의 변경과 함께 그 주변의 변경도 동시에 제어할 수 있기 때문에 다른 트랜잭션이 새로운 레코드를 삽입하여 Phantom Read를 발생시키는 것을 방지한다.
-- 트랜잭션 A 시작
START TRANSACTION;
-- 트랜잭션 A amount = 200인 orders_id = 2 레코드에 대한 레코드 락과 1-2, 2-3에 대한 갭락을 동시에 잠금으로써 넥스트키 락을 설정
SELECT * FROM orders WHERE orders_amount = 200 FOR UPDATE;
-- 트랜잭션 B 시작
START TRANSACTION;
-- 트랜잭션 B orders_id = 4, orders_amount = 200인 레코드 삽입 시도 시, 넥스트키 락으로 인해 차단되어 대기
INSERT INTO orders (orders_id, order_amount) VALUES (4, 200);
...
반응형
'Back-end' 카테고리의 다른 글
[Back-End] 리버스 프록시 vs 포워드 프록시 (0) | 2025.01.13 |
---|---|
[Back-End] CORS란 무엇인가요? (1) | 2025.01.10 |
[Back-End] DBMS에서 동시성을 제어하는 방법 (0) | 2025.01.08 |
[Back-End] 웹사이트에 처음 접근했을 때 발생하는 일련의 과정 (1) | 2025.01.07 |
[Back-End] 스레드, 프로세스, 코어의 수는 많을수록 좋을까요? (2) | 2025.01.02 |