트랜잭션 격리수준 쉽게 이해하기 🔐

트랜잭션 격리수준이란? 🤔

트랜잭션 격리수준은 여러 사용자가 동시에 데이터베이스를 사용할 때, 데이터가 얼마나 안전하게 보호되는지를 결정하는 수준이에요. 쉽게 말해, 여러 사람이 같은 데이터를 동시에 수정하거나 조회할 때 발생할 수 있는 문제를 방지하기 위한 '보호막'이라고 생각하면 됩니다.

🔑 핵심 포인트: 격리수준이 높을수록 데이터는 더 안전하지만, 처리 속도는 느려집니다. 반대로 격리수준이 낮을수록 처리 속도는 빨라지지만, 데이터 일관성에 문제가 생길 수 있어요.

 

트랜잭션 격리수준에서 발생하는 문제들 ⚠️

격리수준을 이해하기 전에, 먼저 발생할 수 있는 문제들을 알아봅시다:

1. Dirty Read 📖🚫

다른 트랜잭션이 아직 완료(커밋)하지 않은 데이터를 읽는 문제에요.

예시

  1. 철수(트랜잭션A)가 자신의 계좌에서 100만원을 인출하는 작업을 시작했어요.
  2. 영희(트랜잭션B)가 철수의 계좌 잔액을 조회했더니 100만원이 차감된 금액(0원)이 보입니다.
  3. 하지만 철수의 인출 작업이 실패해서 취소(롤백)되었어요.
  4. 결과적으로 영희는 잘못된 계좌 잔액 정보를 보게 된 것입니다! 😱

2. Non-Repeatable Read 🔄❌

하나의 트랜잭션 내에서 같은 데이터를 두 번 읽었을 때, 다른 값이 조회되는 문제에요.

예시

  1. 민수(트랜잭션A)가 상품의 가격을 조회했더니 10,000원이었어요.
  2. 그 사이 재훈(트랜잭션B)이 상품 가격을 15,000원으로 수정하고 완료(커밋)했습니다.
  3. 민수가 다시 같은 상품의 가격을 조회했더니 15,000원이 나왔어요.
  4. 민수의 트랜잭션 내에서 같은 데이터를 두 번 읽었는데 다른 결과가 나온 것입니다! 🤯

3. Phantom Read 👻

하나의 트랜잭션 내에서 같은 조건으로 데이터를 조회했을 때, 이전에 없던 행이 나타나거나 있던 행이 사라지는 문제에요.

예시

  1. 지은(트랜잭션A)이 가격이 10,000원 이상인 상품의 목록을 조회했어요 (5개 상품).
  2. 그 사이 태민(트랜잭션B)이 가격이 12,000원인 새 상품을 추가하고 완료(커밋)했습니다.
  3. 지은이 같은 조건(10,000원 이상)으로 다시 조회했더니 6개의 상품이 나왔어요.
  4. 이전에 없던 데이터가 '유령(Phantom)'처럼 나타난 것입니다! 👻

 

격리수준 종류 및 특징 🔍

1. READ UNCOMMITTED (가장 낮은 수준) 🚨

가장 낮은 격리 수준으로, 다른 트랜잭션이 커밋하지 않은 데이터도 읽을 수 있어요.

  • 장점: 매우 빠른 처리 속도 🚀
  • 단점: Dirty Read, Non-Repeatable Read, Phantom Read 모두 발생 가능 ❌❌❌
  • 사용 예: 데이터 일관성보다 속도가 중요한 로그 분석이나 통계 작업
-- MySQL에서 격리수준 설정하기
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

2. READ COMMITTED 📝

커밋된 데이터만 읽을 수 있어요. 대부분의 데이터베이스 시스템의 기본 격리수준입니다.

  • 장점: Dirty Read 방지 ✅
  • 단점: Non-Repeatable Read, Phantom Read 발생 가능 ❌❌
  • 사용 예: 일반적인 웹 애플리케이션의 조회/수정 작업
-- PostgreSQL에서 격리수준 설정하기
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

3. REPEATABLE READ 🔒

트랜잭션이 시작된 시점의 데이터를 계속 일관되게 읽을 수 있어요.

  • 장점: Dirty Read, Non-Repeatable Read 방지 ✅✅
  • 단점: Phantom Read 발생 가능 ❌
  • 사용 예: 동일한 데이터를 여러 번 읽어야 하는 금융 거래
-- MySQL에서 격리수준 설정하기 (MySQL의 기본값)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

4. SERIALIZABLE (가장 높은 수준) 🔒🔒🔒

모든 트랜잭션이 순차적으로 실행되는 것처럼 동작해요. 가장 안전하지만 가장 느립니다.

  • 장점: 모든 문제(Dirty Read, Non-Repeatable Read, Phantom Read) 방지 ✅✅✅
  • 단점: 성능 저하가 심함, 동시성 매우 낮음 🐢
  • 사용 예: 매우 중요한 금융 거래, 예약 시스템
-- Oracle에서 격리수준 설정하기
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

 

실생활 비유로 이해하기 🏫

트랜잭션 격리수준을 도서관 이용 규칙으로 비유해 봅시다

  1. READ UNCOMMITTED: 누군가 책상에 꺼내놓은 책을 허락 없이 가져가서 읽을 수 있어요. (그 사람이 다 읽기도 전에!) 🤭
  2. READ COMMITTED: 누군가 다 읽고 반납한 책만 빌려볼 수 있어요. 하지만 내가 읽는 도중에 업데이트된 새 버전이 나오면 다음번엔 그 책을 보게 될 수 있습니다. 📚
  3. REPEATABLE READ: 내가 책을 빌리기 시작한 시점의 버전으로 끝까지 읽을 수 있어요. 중간에 개정판이 나와도 내가 빌린 버전은 그대로! 하지만 시리즈물의 경우 내가 모르던 새로운 책이 추가될 수 있어요. 📖
  4. SERIALIZABLE: 내가 특정 주제의 책을 보는 동안에는 그 주제의 모든 책에 대한 독점권을 가져요. 아무도 그 주제의 책을 추가하거나 변경할 수 없어요! 🔐

 

어떤 격리수준을 선택해야 할까요? 🤔

격리수준 선택은 안정성과 성능 사이의 균형을 맞추는 과정입니다:

  • 데이터 정확성이 매우 중요한 시스템 (예: 금융, 예약): SERIALIZABLE 또는 REPEATABLE READ
  • 일반적인 웹 애플리케이션: READ COMMITTED
  • 분석이나 리포트 작업: READ UNCOMMITTED (경우에 따라)

대부분의 상황에서는 READ COMMITTED나 REPEATABLE READ가 적절한 선택이에요. 🎯

 

트랜잭션 격리수준은 복잡해 보이지만, 결국 '데이터베이스가 여러 사용자의 요청을 얼마나 안전하게 처리하는가'에 관한 문제입니다. 적절한 격리수준을 선택하면 애플리케이션의 안정성과 성능을 모두 향상시킬 수 있어요! 💪

 


 

트랜잭션 격리수준은 무엇인가요?

트랜잭션의 격리 수준은 동시에 여러 트랜잭션이 실행될 때 한 트랜잭션이

다른 트랜잭션의 연산에 영향을 받지 않도록 하는 정도를 말합니다.

낮은 격리 수준은 동시 처리 능력을 높이지만, 데이터의 일관성 문제를 발생시킬 수 있습니다.

반면, 높은 격리 수준은 데이터의 일관성을 보장하지만, 동시 처리 능력이 떨어질 수 있습니다.

 

즉, 데이터 정합성(여러 데이터 간의 일관성, 또는 모순이나 오류가 없는 상태) 과 성능은 반비례합니다.

트랜잭션 격리 수준은 개발자가 트랜잭션 격리 수준을 설정할 수 있는 기능을 제공하는 기능입니다.

 

트랜잭션 격리 수준은 어떤 것이 있고 각각 어떤 특징이 있나요? 🤔

트랜잭션 격리 수준은 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ가 존재합니다.

 

READ UNCOMMITTED는 커밋이 되지 않은 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 조회하는 것을 허용합니다. 또한 해당 격리 수준에서는 Dirty Read, Phantom Read, Non-Repeatable Read 문제가 발생할 수 있습니다.

 

READ COMMITTED는 커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회할 수 있도록 허용합니다. 특정 트랜잭션이 이루어지는 동안, 다른 트랜잭션은 해당 데이터에 접근할 수 없습니다. Dirty Read는 발생하지 않지만, Phantom Read, Non-Repeatable Read 문제가 발생할 수 있습니다.

 

REPEATABLE READ는 한 트랜잭션에서 특정 레코드를 조회할 때 항상 같은 데이터를 응답하는 것을 보장합니다. 하지만, SERIALIZABLE과 다르게 행이 추가되는 것을 막지는 않습니다. Non-Repeatable Read 문제가 발생하지 않지만, Phantom Read 문제가 발생할 수 있습니다.

 

SERIALIZABLE은 특정 트랜잭션이 사용중인 테이블의 모든 행을 다른 트랜잭션이 접근할 수 없도록 잠급니다. 가장 높은 데이터 정합성을 가지지만 성능이 가장 낮습니다. MySQL의 경우 단순한 SELECT 쿼리가 실행되더라도 데이터베이스 잠금이 걸려 다른 트랜잭션에서 데이터에 접근할 수 없습니다.

 

발생하는 문제를 기준으로 설명을 잘해주셨네요. 그런데 각 문제들은 어떤 문제들인가요? 🤓

Dirty Read는 한 트랜잭션이 다른 트랜잭션이 변경 중인 데이터를 읽는 경우 발생합니다. 다른 트랜잭션이 아직 커밋되지 않은 (즉, 롤백할 가능성이 있는) 데이터를 읽어서, 그 데이터가 나중에 롤백될 경우 트랜잭션의 결과가 변경될 수 있습니다. 이는 데이터의 일관성을 깨뜨릴 수 있습니다.

 

Phantom Read는 한 트랜잭션이 동일한 쿼리를 두 번 실행했을 때, 두 번의 쿼리 사이에 다른 트랜잭션이 삽입, 갱신, 삭제 등의 작업을 수행하여 결과 집합이 달라지는 경우를 말합니다. 이로 인해 한 트랜잭션 내에서 일관성 없는 결과를 가져올 수 있습니다.

 

Non-Repeatable Read는 같은 트랜잭션 안에서 동일한 쿼리를 실행했을 때, 다른 결과를 얻는 경우를 의미합니다. 예를 들어, 한 트랜잭션이 같은 데이터를 두 번 읽을 때, 첫 번째 읽기와 두 번째 읽기 사이에 다른 트랜잭션이 해당 데이터를 변경했을 경우 발생할 수 있습니다.

 
728x90

+ Recent posts