트랜잭션이란 무엇인가?(트랜잭션의 격리 수준과 동시성 제어) - Part2

2025. 2. 13. 09:18·Server Developer/DataBase&Data Engineering
반응형

트랜잭션이 데이터 정합성을 보장하려면 여러 개의 트랜잭션이 동시에 실행될 때도 문제가 없어야해요

하지만 무조건 트랜잭션 간의 독립성을 보장하면 성능이 저하될 수도 있어요

이번 글에서는 트랜잭션이 동시에 실행될 때 발생하는 문제, 이를 해결하는 격리 수준(Isolation Levels), 동시성 문제를 해결하는 기법, 교착 상태(Deadlock) 방지 방법도 함께 살펴볼게요.

 

 

<트랜잭션 시리즈 개요>

☑️ 1편: 트랜잭션의 개념과 ACID 원칙

✅2편: 트랜잭션의 격리 수준과 동시성 제어 (이번 글)

☑️ 3편: 트랜잭션의 내부 동작과 분산 트랜잭션

☑️ 4편: 트랜잭션의 동작 원리와 직렬성 격리

 

 

 

 

 

1. 트랜잭션이 동시 실행될 때 발생하는 문제들

여러 개의 트랜잭션이 동시에 실행되면 데이터 일관성이 깨질 위험이 있어요.

이런 문제를 방지하기 위해 격리 수준을 조절하거나 동시성 제어 기법을 사용해야 해요.

☑️ 더티 읽기 (Dirty Read)

  • 트랜잭션이 커밋되지 않은 데이터를 읽는 문제입니다.
  • 예를 들어, A 사용자가 상품의 재고를 10개에서 5개로 변경하는 트랜잭션을 실행했어요
    • 아직 커밋되지 않았는데 B 사용자가 해당 데이터를 읽으면 재고가 5개로 보일 수 있어요
    • 그런데 A 사용자가 트랜잭션을 롤백하면? B 사용자는 존재하지 않는 데이터를 읽은 것이 됩니다.

☑️ 더티 쓰기 (Dirty Write)

  • 한 트랜잭션이 다른 트랜잭션이 커밋하지 않은 데이터를 덮어쓰는 문제입니다.
  • 예를 들어, A 사용자가 상품 재고를 10개에서 5개로 변경했어요.
    • C 사용자가 같은 상품의 재고 데이터를 10개에서 3개로 변경했는데 A의 트랜잭션이 롤백되면 C의 변경 내용도 잘못될 수 있어요.

☑️ 비반복 읽기 (Non-Repeatable Read)

  • 같은 데이터를 두 번 읽었을 때 값이 달라지는 문제예요.
  • 예를 들어, A 사용자가 상품의 재고를 조회했는데 다른 트랜잭션에서 값이 변경(B 사용자가 재고 변경)되면 다시 조회할 때 값이 달라질 수 있어요.

☑️ 팬텀 읽기 (Phantom Read)

  • 특정 조건으로 검색한 데이터가 트랜잭션 실행 중에 변경되는 문제예요.
  • 예를 들어, 가격이 20만 원 이하인 상품 목록을 조회했는데
    • 다른 트랜잭션이 실행되어 새로운 상품이 추가되거나 기존 상품들의 가격이 변경되면 검색 결과가 달라질 수 있어요

 

 

 

 

 

 

2. 트랜잭션의 격리 수준(Isolation Levels)

이런 동시성 문제를 방지하기 위해 DB의 격리 수준을 조절할 수 있어요.

격리 수준이 높을수록 데이터 정합성이 보장되지만 성능이 낮아지는 단점이 있어요.

→ 격리를 높게하면 트랜잭션 간의 간섭이 줄어들어 정합성이 보장되지만 동시에 처리할 수 있는 트랜잭션의 수는 줄어들어 성능이 낮아집니다.

📌 격리 수준 비교표

격리 수준 더티 읽기 더티 쓰기 비반복 읽기 팬텀 읽기

Read Uncommitted 허용 허용 허용 허용
Read Committed 방지 방지 허용 허용
Repeatable Read 방지 방지 방지 허용
Serializable 방지 방지 방지 방지

다시 한번 이야기 하자면,

격리 수준이 높을수록 데이터 정합성이 보장되지만 트랜잭션 간 충돌(더티 읽기, 더티 쓰기, 비반복 읽기, 팬텀 읽기) 이 증가해서 성능이 저하될 수 있어요.

이제 각 격리 수준에 대해 자세히 살펴볼게요.

1) Read Uncommitted (커밋되지 않은 읽기 허용)

  • 가장 낮은 격리 수준이에요.(모든 문제가 발생 가능함)
  • 다른 트랜잭션이 커밋하지 않은 데이터를 읽을 수 있어요.
  • 성능은 가장 뛰어나겠지만 데이터 정합성이 보장되지 않기 때문에 거의 사용되지 않아요.

☑️ 사용 사례:

  • 데이터 정합성이 중요하지 않은 환경 (로그 저장, 캐시 시스템 등)

2) Read Committed (커밋된 데이터만 읽기 허용)

  • 커밋된 데이터만 읽을 수 있어요.(더티 읽기/쓰기 문제 해결 ↔ 비반복 읽기, 팬텀 읽기 발생)
  • 대부분의 데이터베이스(MySQL, PostgreSQL, Oracle)에서 기본적으로 사용되는 격리 수준이에요.

☑️ 사용 사례:

  • 대부분의 일반적인 웹 애플리케이션

3) Repeatable Read (반복 읽기 보장)

  • 같은 트랜잭션 내에서 같은 데이터를 여러 번 조회해도 값이 변하지 않아요.(더티 읽기/쓰기 문제, 비반복 읽기 해결 ↔ 팬텀 읽기 발생)
  • MySQL InnoDB의 기본 격리 수준이에요.

☑️ 사용 사례:

  • 금융 시스템, 쇼핑몰 결제 시스템 등 데이터 정합성이 중요한 서비스

4) Serializable (직렬성 보장, 가장 강력한 격리 수준)

  • 모든 트랜잭션이 순차적으로 실행되는 것처럼 동작해요.(더티 읽기/쓰기, 비반복 읽기, 팬텀 읽기 모두 해결)
  • 하지만 성능이 크게 저하될 수 있기 때문에 잘 사용되지 않습니다

☑️ 사용 사례:

  • 데이터 정합성이 절대적으로 중요한 금융 서비스

 

 

 

 

 

3. 동시성 문제 해결 기법

트랜잭션 간의 충돌을 방지하기 위해 잠금(Locking)과 다중 버전 동시성 제어(MVCC) 같은 기법이 사용돼요.

1) 잠금(Locking) 기법

  • 공유 잠금(Shared Lock, S-Lock): 여러 트랜잭션이 데이터를 읽을 수 있지만 변경은 불가능해요.
  • 배타 잠금(Exclusive Lock, X-Lock): 한 트랜잭션만 데이터를 수정할 수 있어요.

 

2) 다중 버전 동시성 제어 (MVCC, Multi-Version Concurrency Control)

MVCC는 트랜잭션이 실행될 때 데이터를 읽을 수 있도록 별도의 "스냅샷(Snapshot)"을 유지하는 방식이에요.

즉, 트랜잭션이 실행되는 동안 다른 트랜잭션의 변경 사항을 보지 않고 실행하는 트랜잭션의 시작 시점 데이터를 기준으로 작업을 수행해요

Postgres-XL and global MVCC (https://www.enterprisedb.com/blog/postgres-xl-and-global-mvcc)

 

☑️ MVCC의 특징

  • 읽기 트랜잭션(Read-Only Transaction)은 잠금 없이 데이터를 조회할 수 있어 성능이 뛰어나요.
  • 쓰기 트랜잭션(Write Transaction)은 충돌이 발생하면 롤백될 수도 있어요.

☑️ MVCC 동작 방식

  1. 트랜잭션이 시작되면 현재 시점의 데이터를 기준으로 "스냅샷"을 생성해요.
  2. 다른 트랜잭션이 데이터를 변경하더라도 기존 트랜잭션은 자신이 시작할 때 조회한 데이터만 보게 돼요.
  3. 트랜잭션이 완료되면 최신 데이터로 갱신되거나 충돌이 발생하면 롤백될 수 있어요.

 

<MVCC를 지원하는 데이터베이스>

MVCC는 MySQL InnoDB, PostgreSQL, Oracle 등의 데이터베이스에서 사용돼요.
예를 들어, PostgreSQL에서는 SELECT 문을 실행할 때 다른 트랜잭션의 변경 사항을 보지 않도록 MVCC를 자동으로 적용해요.

 

➡ MVCC를 사용하면 트랜잭션 간 충돌을 줄이면서도 읽기 성능을 높일 수 있지만 오래된 데이터 버전을 관리하는 비용이 발생할 수 있어요.

따라서 데이터 변경이 자주 발생하는 시스템에서는 MVCC보다 적절한 잠금 전략을 병행해서 사용하는 것이 중요합니다.!

 

 

 

 

 

 

 

정리하며

이번 글에서는 트랜잭션의 격리 수준과 동시성 문제 해결 방법을 살펴봤어요.

📌 핵심 정리

☑️ 여러 트랜잭션이 동시에 실행될 때 더티 읽기, 비반복 읽기, 팬텀 읽기 문제가 발생할 수 있어요.

☑️ 격리 수준이 높을수록 데이터 정합성이 보장되지만, 성능이 저하될 수 있어요.

☑️ 잠금(Locking)과 MVCC 같은 기법을 활용하면 동시성 문제를 해결할 수 있어요.

다음 글에서는 트랜잭션의 내부 동작과 분산 트랜잭션에 대해 다룰 예정이에요.

 

 

 

 

 

 

 

📌 다음 편 예고: "트랜잭션의 내부 동작과 분산 트랜잭션 (3편)"

  • 트랜잭션의 내부 동작 (MVCC, Undo Log, Redo Log)
  • 2단계 커밋(2PC)과 3단계 커밋(3PC)
  • 분산 시스템에서의 트랜잭션 관리 방법

트랜잭션이 실제로 어떻게 동작하는지 자세히 살펴볼게요!

 

 

 

 

이 글은 마틴 클레프만(Martin Kleppmann)의 데이터 중심 애플리케이션 설계(Designing Data-Intensive Applications) 책을 참고하여 작성되었습니다. 확장 가능하며 유지보수하기 쉬운 데이터 시스템을 설계하는 핵심 개념을 다루고 있습니다.

반응형
저작자표시 (새창열림)

'Server Developer > DataBase&Data Engineering' 카테고리의 다른 글

트랜잭션이란 무엇인가?(트랜잭션의 기본 개념, 중요성, ACID 원칙) - Part1  (1) 2025.02.13
[DataBase] Homebrew를 사용하여 MySQL 설치하기 (Mac M1 Pro)  (1) 2023.01.23
'Server Developer/DataBase&Data Engineering' 카테고리의 다른 글
  • 트랜잭션이란 무엇인가?(트랜잭션의 기본 개념, 중요성, ACID 원칙) - Part1
  • [DataBase] Homebrew를 사용하여 MySQL 설치하기 (Mac M1 Pro)
성 언
성 언
AI 학과 3학년 학생이자 RAG 기반 LLM 챗봇 개발 회사에서 근무 중입니다. AI 챗봇 개발과 관련된 기술, 연구, 그리고 실험 과정에서 얻은 인사이트를 공유합니다. 최신 AI 기술을 함께 탐구하며 성장해 나가요!
    반응형
  • 성 언
    AI EON
    성 언
  • 전체
    오늘
    어제
    • AII
      • NLP
      • AI Paper Review
      • MLOps
      • Python
      • Algorithm
      • Memo
      • Server Developer
        • Node.js
        • DataBase&Data Engineering
        • Server Basic
      • MATH
        • Linear Algebra
        • AI
      • etc
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Signature 초격차 패키지
    map 함수
    파이썬 문서 자동화
    트랜잭션
    NVML
    패스트캠퍼스 수강 후기
    배열의 모양 변경
    비반복 읽기
    문서 자동화
    [Numpy] squeeze & unsqueeze
    transaction
    reranker
    Python
    다중 버전 동시성 제어
    리랭커
    docx-template
    배타 잠금
    그리디 알고리즘
    더티 읽기
    c++
    알고리즘
    파이썬
    백준
    더티 쓰기
    node.js
    Ubuntu-20.04 APM 소스 설치
    팬텀 읽기
    word 자동화
    umc
    스택
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
성 언
트랜잭션이란 무엇인가?(트랜잭션의 격리 수준과 동시성 제어) - Part2
상단으로

티스토리툴바