반응형
MySQL에서 데이터를 읽기 전용으로 안전하게 조회하고 싶을 때 사용할 수 있는 키워드가 있다. 바로 LOCK IN SHARE MODE이다. 이 문법은 다른 트랜잭션이 같은 데이터를 변경하지 못하게 하면서, 내가 읽은 데이터를 신뢰할 수 있도록 보호해준다.
✅ LOCK IN SHARE MODE란?
SELECT ... LOCK IN SHARE MODE는 InnoDB 테이블에서 사용하는 공유 잠금(Shared Lock) 쿼리이다. 이 구문을 실행하면 지정된 행에 공유 잠금이 설정되어, 다른 트랜잭션이 해당 행을 UPDATE 또는 DELETE하지 못하게 막는다.
즉, 읽기 작업은 가능하지만, 쓰기 작업은 차단되는 안전한 데이터 읽기 방식이다.
기본 문법
START TRANSACTION;
SELECT * FROM products WHERE id = 1001 LOCK IN SHARE MODE;
-- 이후 트랜잭션이 끝날 때까지 다른 세션은 해당 행 수정 불가
COMMIT;
이 쿼리는 products 테이블에서 ID가 1001인 상품 정보를 공유 잠금으로 조회하는 예이다.
반응형
✅ 왜 사용하는가?
LOCK IN SHARE MODE는 다음과 같은 상황에서 유용하다.
- 데이터를 읽고 그대로 사용할 예정인데, 그 사이 다른 사용자가 해당 데이터를 수정하면 안 되는 경우
- 외래 키 참조 무결성을 보장하기 위해 상위 테이블 데이터를 고정할 필요가 있을 때
- 여러 트랜잭션 간에 읽기 충돌을 피하면서도 정합성 있는 조회를 하고 싶을 때
✅ 실전 예제 1: 외래 키 참조 무결성 확보
START TRANSACTION;
SELECT id FROM categories WHERE name = '의류' LOCK IN SHARE MODE;
INSERT INTO products (name, category_id) VALUES ('청바지', 3);
COMMIT;
위 예제는 categories 테이블에서 특정 카테고리 ID를 공유 잠금으로 가져온 뒤, 그 ID를 참조하여 products 테이블에 데이터를 삽입하는 구조이다. 이때 다른 트랜잭션이 categories의 해당 ID 행을 삭제하거나 수정하는 것을 방지할 수 있다.
✅ 실전 예제 2: 재고 확인 후 다른 테이블 갱신
START TRANSACTION;
SELECT stock FROM items WHERE id = 2001 LOCK IN SHARE MODE;
INSERT INTO audit_log (item_id, message) VALUES (2001, '재고 확인 완료');
COMMIT;
위 쿼리는 items 테이블의 재고 수량을 안전하게 확인하고, 이후 로깅 테이블에 해당 정보를 기록하는 구조이다. 이 경우 실제 stock 값을 변경하지 않기 때문에 FOR UPDATE보다는 LOCK IN SHARE MODE가 더 적절하다.
✅ LOCK IN SHARE MODE vs FOR UPDATE 차이
항목 | LOCK IN SHARE MODE | FOR UPDATE |
잠금 종류 | 공유 잠금 (Shared Lock) | 배타 잠금 (Exclusive Lock) |
다른 세션의 읽기 가능 여부 | 가능 | 가능 |
다른 세션의 쓰기 가능 여부 | 불가능 | 불가능 |
사용 목적 | 정합성 있는 읽기 전용 조회 | 수정/삭제 전의 데이터 잠금 |
반응형
사용 권장 케이스
- 데이터를 읽기만 하고, 수정하지 않을 때는 LOCK IN SHARE MODE를 사용
- 데이터를 조회 후 수정할 가능성이 있다면 FOR UPDATE 사용
✅ LOCK IN SHARE MODE 사용 시 주의사항
- 반드시 트랜잭션 안에서만 사용 가능하다. 그렇지 않으면 아무 효과도 없다.
- MyISAM 스토리지 엔진은 지원하지 않는다. 반드시 InnoDB 테이블에서만 사용해야 한다.
- WHERE 조건을 생략하면 테이블 전체에 공유 잠금이 걸릴 수 있으므로 위험하다.
✅ 성능 최적화 팁
- 가능한 한 짧은 시간 안에 트랜잭션을 종료하는 것이 좋다.
- 명확한 WHERE 절을 통해 잠금 범위를 최소화하는 것이 효율적이다.
- 잠금 대상 컬럼에 인덱스를 설정하면 성능이 향상된다.
✅ 공식 가이드 문서
- InnoDB Locking Reads:
https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html - Transaction Isolation Levels:
https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
반응형
'DB' 카테고리의 다른 글
[MySQL] UNION과 UNION ALL 완전정복 – 다중 SELECT 결과 통합의 모든 것 (0) | 2025.06.30 |
---|---|
[MySQL] ENUM 성능 최적화와 실무 활용 팁 총정리 (0) | 2025.06.30 |
[MySQL] SELECT와 ENUM 컬럼을 활용한 데이터 정합성 및 조회 최적화 전략 (1) | 2025.06.30 |
[MySQL] SELECT 쿼리를 VIEW로 추상화 (복잡한 SQL을 깔끔하게 관리) (1) | 2025.06.30 |
[MySQL] SELECT FOR UPDATE 완벽 가이드 – 동시성 제어의 핵심 키워드 (0) | 2025.06.30 |
[MySQL] JSON 컬럼 SELECT 조회 완벽 가이드 (0) | 2025.06.26 |
[MySQL] LIKE와 REGEXP 차이부터 고급 패턴 검색까지 완벽 정리 (0) | 2025.06.26 |
[MySQL] IS NULL과 IS NOT NULL 완전 정복! 조건절로 놓치지 말아야 할 핵심 포인트 (2) | 2025.06.26 |