[Lock-3][Optimization] Lock: 격리성 수준(Isolation Level) 심층 분석 및 실습

2025. 12. 25. 11:45·Database/MySQL

1. 들어가며: 격리 수준은 왜 필요한가?

 이전 포스팅에서 다중 트랜잭션 환경에서 데이터베이스의 가장 큰 숙제는 데이터의 정합성(Consistency) 유지와 시스템 성능(Performance)의 최적화 사이에서 균형을 잡는 일이라는 것을 알았다. 모든 트랜잭션을 하나씩 순차적으로 처리하면 정합성은 완벽하겠지만, 수많은 요청이 몰리는 현대 서비스에서 이는 불가능에 가깝다. 반대로 성능을 위해 모든 간섭을 허용하면 데이터는 아수라장이 될 것이다.

 

 이러한 문제를 해결하기 위해 도입된 개념이 바로 격리성 수준(Isolation Level)이다. 이는 "여러 트랜잭션이 동시에 실행될 때, 서로의 연산을 어디까지 노출하고 격리할 것인가"를 정의하는 설정이다.


2. 격리성 수준(Isolation Level)의 개요

격리성 수준은 총 4단계로 나뉘며, 수준이 높아질수록 데이터 정합성은 강력해지지만 동시 처리 성능은 떨어진다.

  1. Read Uncommitted (읽기 허용, 커밋 안 됨)
  2. Read Committed (커밋된 데이터만 읽기 허용)
  3. Repeatable Read (반복 가능한 읽기 보장)
  4. Serializable (가장 엄격한 격리성)

3. Read Uncommitted: 가장 낮은 격리 수준

다른 트랜잭션이 커밋(COMMIT)하지 않은 데이터를 읽는 것을 허용하는 단계이다.

3.1. 특징 및 실사례

  • 실사례 (로그 시스템): 로그 데이터처럼 일부 부 정확하거나 롤백되어도 비즈니스에 치명적이지 않은 경우, 정교한 정합성보다는 최상의 실시간 성능이 중요할 때 제한적으로 사용된다.
  • 부적절한 경우: 금융 시스템이나 재고 관리처럼 1원의 오차도 허용되지 않는 곳에서는 절대 사용해서는 안 된다.

3.2. 실습 코드

-- Session A
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
UPDATE accounts SET balance = 500 WHERE id = 1; -- 아직 COMMIT 안 함

-- Session B
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
SELECT * FROM accounts WHERE id = 1; -- 500원 조회됨 (Dirty Read)

-- Session A
ROLLBACK; -- 원래 1000원으로 복구되었으나, Session B는 이미 500원으로 판단함

3.3. 해결되지 않는 문제: Dirty Read (더티 리드)

트랜잭션 A가 데이터를 수정 중인 상태에서 트랜잭션 B가 해당 데이터를 읽었는데, 이후 트랜잭션 A가 작업을 취소(ROLLBACK)하는 경우 발생한다. 트랜잭션 B는 실제 DB에 반영되지도 않은 '더러운(Dirty)' 데이터를 읽게 되는 것이다. 이를 해결하기 위해 '커밋된 데이터만 읽기'라는 개념이 등장한다.


4. Read Committed: 커밋된 데이터만 읽기

트랜잭션이 커밋된 데이터만 조회하도록 보장한다. 오라클(Oracle)이나 SQL Server의 기본 격리 수준이다.

4.1. 특징 및 실사례

  • 특징: 온라인 서비스에서 가장 많이 선택되는 수준으로, 더티 리드를 방지하면서도 적절한 성능을 유지한다.
  • 실사례: 뉴스 기사나 쇼핑몰 상품 정보 등은 사용자가 페이지를 보는 동안 수정되어 커밋되면, 다음 조회 시 변경된 값이 보여도 큰 무리가 없다.

4.2. 실습 코드

-- Session B
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT * FROM accounts WHERE id = 1; -- 첫 번째 조회 (1000원)

-- Session A
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
UPDATE accounts SET balance = 500 WHERE id = 1;
COMMIT; -- 커밋 완료

-- Session B
SELECT * FROM accounts WHERE id = 1; -- 두 번째 조회 (500원, 값이 달라짐!)

4.3. 해결되지 않는 문제: Non-Repeatable Read (반복 불가능한 읽기)

하나의 트랜잭션 내에서 똑같은 SELECT 쿼리를 두 번 실행했을 때 결과가 서로 다른 현상이다. 트랜잭션 B가 한 트랜잭션 내에서 데이터를 두 번 조회하는 사이, 트랜잭션 A가 데이터를 수정하고 커밋해버리면 발생한다. 데이터의 일관된 '스냅샷'을 유지해야 하는 업무에서는 치명적인 문제가 되며, 이를 위해 Repeatable Read가 필요해진다.


5. Repeatable Read: 반복 가능한 읽기 보장

자신의 트랜잭션이 시작된 시점을 기준으로 데이터의 스냅샷을 생성하여, 트랜잭션이 끝날 때까지 항상 동일한 데이터를 보도록 보장한다. MySQL(InnoDB)의 기본 격리 수준이다.

5.1. 상세 메커니즘: MVCC(Multi-Version Concurrency Control)

많은 이들이 오해하는 부분 중 하나가 "Repeatable Read가 다른 트랜잭션의 Update를 막는 것인가?"라는 점이다. 결론부터 말하면 아니다. Repeatable Read는 다른 트랜잭션의 수정을 막는 것이 아니라, 나에게 보여주는 데이터의 버전을 고정(Versioning)하는 방식이다.

  • Undo 로그 활용: 트랜잭션이 시작되면 고유한 트랜잭션 번호가 부여된다. 다른 트랜잭션이 데이터를 수정하고 커밋하더라도, 현재 트랜잭션보다 번호가 큰(나중에 시작된) 트랜잭션이 변경한 내용은 Undo 영역에 백업된 이전 버전의 데이터를 읽어옴으로써 데이터의 일관성을 유지한다.
  • 즉, '수정' 자체를 막는 것이 아니라 '수정된 결과'가 나의 현재 트랜잭션에 영향을 주지 못하게 격리하는 것이 핵심이다.

5.2. 실습 코드 (MySQL 기준)

-- Session B
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT * FROM accounts; -- 초기 데이터 1건 확인

-- Session A
START TRANSACTION;
INSERT INTO accounts (name, balance) VALUES ('NewUser', 2000);
COMMIT; -- 새로운 유저 삽입 후 커밋

-- Session B
SELECT * FROM accounts; -- 여전히 1건 (MVCC 덕분에 팬텀 리드 방지됨)
SELECT * FROM accounts FOR UPDATE; -- 2건 조회됨! (쓰기 락을 거는 순간 팬텀 리드 발생)

5.3. 해결되지 않는 문제: Phantom Read (팬텀 리드)

기존 레코드의 수정은 MVCC를 통해 방지하지만, 새로운 레코드가 삽입(INSERT)되는 경우 이전에 없던 데이터가 나타나는 현상이다.

  • 원인: 범위 조회(Range Query) 시, 이전 조회 때는 없던 '유령(Phantom)' 같은 레코드가 추가로 발견되는 문제이다.
  • 주의: MySQL InnoDB는 일반적인 SELECT에서는 넥스트 키 락(Next-Key Lock) 등을 통해 이를 상당 부분 방지하지만, SELECT ... FOR UPDATE와 같이 쓰기 락을 거는 쿼리를 사용할 경우 언두 로그가 아닌 실제 현재 데이터를 읽어오게 되어 팬텀 리드가 발생할 수 있다.

6. Serializable: 가장 엄격한 격리

가장 높은 수준의 격리이다. 읽기 작업에도 공유 잠금(S-Lock)을 걸어, 다른 트랜잭션이 해당 데이터를 수정하거나 새로운 데이터를 삽입하는 것을 완벽히 차단한다.

  • 특징: 모든 트랜잭션이 사실상 순차적으로 실행되는 것과 같아 데이터 정합성은 완벽하지만, 성능 저하가 극심하다.
  • 실사례: 현대적인 대규모 서비스에서는 거의 사용되지 않는다. 정합성이 극도로 중요하다면 이 레벨을 쓰기보다 애플리케이션 레벨에서 별도의 분산 락을 활용하는 경우가 많다.


7. 격리성 수준 요약 테이블

격리성 레벨 Dirty Read Non-Repeatable Read Phantom Read 성능 사용 사례
Read Uncommitted 발생함 😱 발생함 😱 발생함 😱 최고 성능 로그 시스템, 실시간 대시보드
Read Committed 방지됨 ✅ 발생함 😱 발생함 😱 일반적인 성능 게시판, 뉴스 검색, 쇼핑몰
Repeatable Read 방지됨 ✅ 방지됨 ✅ 발생함 😱 적당한 성능 은행 계좌 조회, 게임 랭킹 시스템
Serializable 방지됨 ✅ 방지됨 ✅ 방지됨 ✅ 최저 성능 없음

 

'Database > MySQL' 카테고리의 다른 글

[Lock-5][Optimization]트랜잭션 실습을 통한 동시성 문제 인식  (0) 2025.12.25
[Lock-4][Optimization] Redo/Undo 로그와 MVCC 원리  (0) 2025.12.25
[Lock-2][Optimization] 다중 트랜잭션 환경과 정합성 문제  (0) 2025.12.24
[Lock-1][Optimization] 트랜잭션의 정의와 ACID 원칙  (0) 2025.12.24
[Index-7][Optimization] 실무 적용(⭐) - 복합 인덱스/집계 테이블/반정규화  (0) 2025.12.24
'Database/MySQL' 카테고리의 다른 글
  • [Lock-5][Optimization]트랜잭션 실습을 통한 동시성 문제 인식
  • [Lock-4][Optimization] Redo/Undo 로그와 MVCC 원리
  • [Lock-2][Optimization] 다중 트랜잭션 환경과 정합성 문제
  • [Lock-1][Optimization] 트랜잭션의 정의와 ACID 원칙
h6bro
h6bro
백엔드 개발자의 기술 블로그
  • h6bro
    Jun's Tech Blog
    h6bro
  • 전체
    오늘
    어제
    • 분류 전체보기 (250) N
      • Java (18)
        • Core (9)
        • Design Pattern (9)
      • Spring (80)
        • Core (24)
        • MVC (6)
        • DB (10)
        • JPA (26)
        • Monitoring (3)
        • Security (11)
        • WebSocket (0)
      • Database (33)
        • Redis (15)
        • MySQL (18)
      • MSA (25) N
        • MSA 기본 (11)
        • MSA 아키텍처 (14) N
      • Kafka (30) N
        • Core (18) N
        • Connect (12)
      • ElasticSearch (11)
        • Search (11)
        • Logging (0)
      • Test (4)
        • k6 (4)
      • Docker (9)
      • CI&CD (10)
        • GitHub Actions (6)
        • ArgoCD (4)
      • Kubernetes (18)
        • Core (12)
        • Ops (6)
      • Cloud Engineering (4)
        • AWS Infrastructure (3)
        • AWS EKS (1)
        • Terraform (0)
      • Project (8)
        • LinkFolio (1)
        • Secondhand Market (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • Cloud Engineering 포스팅 정리
  • 인기 글

  • 태그

    ㅈ
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
h6bro
[Lock-3][Optimization] Lock: 격리성 수준(Isolation Level) 심층 분석 및 실습
상단으로

티스토리툴바