Database 격리수준

jongeun·2023년 4월 5일
0
post-custom-banner

격리수준이란?

동시에 여러 트랜잭션이 실행 될 때, 한 트랜잭션이 다른 트랜잭션에 의해 수행된 변경 사항을 어느 정도 볼 수 있는지 정의하는 것
각 데이터베이스 관리시스템은 이러한 격리 수준 중 하나를 기본값으로 설정하며, 필요에 따라 개발자가 변경할 수 있음

  • 데이터베이스 성능과 데이터 무결성 사이의 균형을 맞추는 데 중요한 역할을
  • 격리수준은 동시에 여러작업(트랜잭션)이 데이터베이스에서 실행될때 서로 어떻게 영향을 미치는지를 결정하는 규칙
  • 격리수준은 데이터의 정확성과 성능 사이의 균형을 조절하는데 중요한 역할을 함
  • 예를들어, 은행계좌에서 돈을 이체하는 상황
    • 두명의 사용자가 동시에 같은 계좌에서 다른 계좌로 돈을 보내려고함
  1. Read Uncommitted (읽기 미완료): 가장 낮은 격리 수준
    • 한 트랜잭션이 다른 트랜잭션의 아직 커밋되지 않은 변경 사항을 읽을 수 있습니다.
    • 이 격리 수준에서는 "더티 리드(Dirty Read)"와 같은 문제가 발생할 수 있습니다.
    • 한 사용자가 돈을 이체하는 동안, 다른 사용자는 그 이체가 완료되지 않았음에도 불구하고 변경 된 잔액을 볼 수 있음
  2. Read Committed (읽기 완료): 한 트랜잭션이 다른 트랜잭션의 변경 사항을 볼 수 있지만, 그 변경 사항이 커밋된 경우에만 가능
    • 이 격리 수준은 "더티 리드" 문제를 해결하지만, "논리적 모순(Non-Repeatable Read)" 문제는 여전히 발생할 수 있음
    • 한사용자가 돈을 이체한 후에만 다른 사용자가 변경 된 잔액을 볼 수 있음
    • 이 경우, 이체가 완료된 후에만 올바른 정보를 제공
    • 그러나 동시에 두 번 이상의 조회를 수행할 경우 일관성 없는 결과가 발생할 수 있음
  3. Repeatable Read (반복 가능한 읽기): 이 격리 수준에서는 한 트랜잭션 동안 다른 트랜잭션의 변경 사항을 볼 수 없음
    • 따라서 같은 데이터를 반복해서 읽어도 같은 결과를 얻을 수 있습니다. 이 격리 수준은 "더티 리드"와 "논리적 모순" 문제를 해결하지만, "팬텀 리드(Phantom Read)" 문제는 여전히 발생할 수 있음
    • 한 사용자가 돈을 이체하는 동안 다른 사용자는 이체 전의 잔액을 계쏙해서 볼 수 있음
    • 이 경우, 사용자는 이체가 완료되기 전까지 일관된 정보를 얻을 수 있음
    • 그러나, 이 수준에서도 특정 조건에서 일관성 없는 결과가 발생할 수 있음
  4. Serializable (직렬화 가능): 가장 높은 격리 수준으로, 트랜잭션들이 순차적으로 실행되는 것처럼 보장됨
    • 이 격리 수준에서는 "더티 리드", "논리적 모순" 및 "팬텀 리드" 문제가 모두 해결됨
    • 하지만 이러한 고립 수준은 성능에 부정적인 영향을 미칠 수 있음
    • 사용자 a의 이체가 완료되기 전까지 사용자 b의 이체는 기다려야함
    • 데이터의 일관성이 가장 높지만 성능이 저하 될 수 있음

예제

  1. Read Uncommitted (읽기 미완료): 고객이 사과를 구매하려고 결제를 진행 중입니다. 이때 B 고객이 사과 재고를 확인하면, A 고객의 결제가 완료되지 않았음에도 사과 재고가 줄어든 것으로 표시됩니다. 이렇게 변경 사항이 확정되지 않은 상태에서 다른 트랜잭션이 그 결과를 확인할 수 있는 상황을 "더티 리드(Dirty Read)"라고 합니다.
  2. Read Committed (읽기 완료): A 고객이 사과를 구매하려고 결제를 진행 중입니다. 이때 B 고객이 사과 재고를 확인하면, A 고객의 결제가 완료된 후에만 사과 재고가 줄어든 것으로 표시됩니다. => 결제 진행중일때는 사과가 있음
    B 고객이 재고를 다시 확인하려고 할 때, A 고객의 결제가 완료되어 재고가 달라질 수 있습니다. 이렇게 동일한 트랜잭션 내에서 같은 데이터를 조회했을 때 결과가 다른 상황을 "논리적 모순(Non-Repeatable Read)"이라고 합니다.
  3. Repeatable Read (반복 가능한 읽기): A 고객이 사과를 구매하려고 결제를 진행 중입니다. 이때 B 고객이 사과 재고를 확인하면, A 고객의 결제가 진행되는 동안 B 고객은 처음에 확인했던 사과 재고와 동일한 값을 볼 수 있습니다. 그러나 B 고객이 사과 종류를 바꾸려고 하면, A 고객의 결제 완료 후에 추가된 사과 종류(이전에 없던 사과)를 확인할 수 있게 됩니다. 이렇게 새로운 데이터가 생겨 기존 결과와 일관성이 깨지는 상황을 "팬텀 리드(Phantom Read)"라고 합니다.

    Read Uncommitted는 변경 사항이 확정되지 않은 상태에서 다른 트랜잭션이 그 결과를 확인할 수 있고, Read Committed는 변경 사항이 확정된 후에만 다른 트랜잭션이 결과를 확인

  4. Serializable (직렬화 가능): A 고객이 사과를 구매하려고 결제를 진행 중입니다. 이때 직렬화 가능 격리 수준에서는 다른 트랜잭션인 B 고객이 사과 재고를 확인하거나 구매하는 것이 A 고객의 결제가 완료될 때까지 기다려야 합니다. 즉, 한 번에 하나의 트랜잭션만 실행되는 것처럼 처리됩니다.

    A 고객의 결제가 진행되는 동안, B 고객은 사과 재고를 확인하거나 구매할 수 없습니다. B 고객은 A 고객의 결제가 완료된 후에만 사과 재고를 확인하거나 구매할 수 있습니다.
    이 격리 수준에서는 "더티 리드(Dirty Read)", "논리적 모순(Non-Repeatable Read)", 그리고 "팬텀 리드(Phantom Read)"와 같은 문제가 발생하지 않습니다. 그 이유는 각 트랜잭션이 순차적으로 실행되므로, 데이터의 일관성이 유지되기 때문입니다.

django의 격리수준은?

Django는 데이터베이스 관리 시스템(DBMS)에 따라 다양한 격리 수준을 지원합니다. Django 자체에는 기본 격리 수준이 정의되어 있지 않으며, 사용하는 데이터베이스 엔진의 기본 격리 수준을 따름

  • PostgreSQL: 기본적으로 Read Committed 격리 수준을 사용
  • MySQL: InnoDB 스토리지 엔진을 사용하는 경우 기본적으로 Repeatable Read 격리 수준을 사용하며, MyISAM 스토리지 엔진은 격리 수준을 지원하지 않음
  • SQLite: 기본적으로 Serializable 격리 수준을 사용
profile
기록으로 성장하는 개발자 되기
post-custom-banner

0개의 댓글