DB

DB 격리 수준(ACID > Isolation)

Raconer 2023. 6. 15. 21:16
728x90

ACID

  • Atomicity (원자성)
    • 트랜잭션은 원자적(Atomic) 단위로 처리되어야 합니다.
    • 이는 트랜잭션 내의 모든 작업이 전부 성공하거나 전부 실패하는 것을 의미합니다.
    • 트랜잭션은 모두 실행되거나 전혀 실행되지 않아야 하며, 중간 단계의 부분적인 성공 또는 실패가 허용되지 않습니다.
  • Consistency (일관성)
    • 트랜잭션이 실행 전과 실행 후의 데이터베이스 상태를 일관성 있게 유지해야 합니다.
    • 트랜잭션은 미리 정의된 규칙과 제약조건을 준수하여 데이터베이스의 무결성을 유지해야 합니다.
  • Isolation (격리성)
    • 동시에 여러 개의 트랜잭션이 실행될 때, 각각의 트랜잭션은 다른 트랜잭션으로부터 독립되어야 합니다.
    • 격리성은 한 트랜잭션이 다른 트랜잭션에 의해 영향을 받지 않도록 하는 것을 의미합니다.
    • 이를 통해 각 트랜잭션은 마치 독립적으로 실행되는 것처럼 보이게 됩니다.
  • Durability (지속성)
    • 트랜잭션이 성공적으로 완료되면, 그 결과는 영구적으로 저장되어야 합니다.
    • 이는 트랜잭션이 커밋된 후에는 데이터의 변경 사항이 지속되고, 시스템 장애 또는 전원 장애와 같은 상황에서도 데이터의 안정성을 보장하는 것을 의미합니다.

Isolation

트랜잭션은 데이터베이스에서 논리적인 작업 단위를 의미하며, 여러 개의 트랜잭션이 동시에 실행될 경우 데이터의 무결성을 해치지 않도록 보장해야 합니다.
이를 위해 트랜잭션들은 상호 간섭 없이 독립적으로 실행되어야 합니다.
이렇게 동시에 실행되는 트랜잭션들 간에 데이터 일관성을 유지하기 위해 트랜잭션 격리 수준(isolation level)과 다양한 동시성 제어 기법을 사용합니다.

가장 일반적으로 사용되는 트랜잭션 격리 수준은 ACID(Atomicity, Consistency, Isolation, Durability) 원칙에 따라 정의된 네 가지 수준입니다.
이 수준들은 트랜잭션의 격리 수준을 점진적으로 강화시키며, 강화될수록 동시성은 감소하고 데이터 일관성은 증가합니다.
ACID 원칙에 따른 네 가지 격리 수준은 다음과 같습니다.

종류 및 예시

  1. Read Uncommitted (미커밋된 읽기)
    • 특징
      • 가장 낮은 격리 수준이며, 트랜잭션의 변경 내용이 커밋되지 않아도 다른 트랜잭션에서 해당 변경 내용을 읽을 수 있습니다.
      • 동시성은 높지만 데이터 일관성과 안정성에 문제가 있을 수 있습니다.
      • 트랜잭션이 시작되면 다른 트랜잭션에 의해 변경된 데이터를 읽을 수 있습니다.
    • 예시
      1. 통장 잔액이 100달러인 상황에서 트랜잭션 A가 50달러를 출금합니다.
      2. 출금 중인 동안 트랜잭션 B가 통장 잔액을 읽어들입니다.
      3. 트랜잭션 B는 아직 트랜잭션 A의 변경 사항이 커밋되지 않은 상태에서 통장 잔액을 100달러로 읽을 수 있습니다.
      4. 그 후, 트랜잭션 B가 30달러를 입금합니다.
      5. 트랜잭션 B의 입금이 커밋되어 통장 잔액이 130달러로 변경됩니다.
      6. 이후 트랜잭션 A의 출금이 커밋되어 통장 잔액이 50달러로 변경됩니다.
  2. Read Committed (커밋된 읽기)
    • 특징
      • 트랜잭션의 변경 내용이 커밋된 후에만 다른 트랜잭션에서 해당 변경 내용을 읽을 수 있습니다.
      • 일관성과 안정성은 개선되지만, 동시성에 여전히 문제가 있을 수 있습니다.
      • 트랜잭션이 시작된 후에만 다른 트랜잭션에 의해 변경된 데이터를 읽을 수 있습니다.
    • 예시 결과
      1. 통장 잔액이 100달러인 상황에서 트랜잭션 A가 50달러를 출금합니다.
      2. 트랜잭션 A의 출금이 커밋되고 통장 잔액이 50달러로 변경됩니다.
      3. 출금이 완료된 후, 트랜잭션 B가 통장 잔액을 읽어들입니다.
      4. 트랜잭션 B는 최신의 커밋된 변경 사항을 읽게 됩니다. 따라서, 통장 잔액이 50달러로 나타나고, 이후 B가 30달러를 입금합니다.
      5. 트랜잭션 B의 입금이 커밋되어 통장 잔액이 80달러로 변경됩니다.
  3. Repeatable Read (반복 가능한 읽기)
    • 특징
      • 동일한 쿼리를 여러 번 실행해도 결과가 동일하게 유지됩니다.
      • 트랜잭션이 시작된 시점에서 읽은 데이터는 트랜잭션이 종료될 때까지 변경되지 않습니다.
      • 일관성과 안정성은 더욱 향상되지만, 동시성에는 여전히 문제가 있을 수 있습니다.
      • 트랜잭션이 시작된 시점에서 읽은 데이터는 트랜잭션이 종료될 때까지 변경되지 않습니다.
    • 예시 결과
      1. 통장 잔액이 100달러인 상황에서 트랜잭션 A가 50달러를 출금합니다.
      2. 출금 중인 동안 트랜잭션 B가 통장 잔액을 읽어들입니다.
      3. Repeatable Read 격리 수준에서는 트랜잭션 B가 이전에 읽은 값을 유지합니다. 따라서, B는 출금되기 전에 통장 잔액을 100달러로 읽게 됩니다.
      4. A가 50달러를 출금 하여 계좌에는 50달러가 됩니다.
      5. 이후, 트랜잭션 B가 30달러를 입금합니다.
      6. 트랜잭션 B의 입금이 커밋되어 통장 잔액이 130달러(읽은 시점이 트랜잭션 시작 시점 이므로 최초 100달러가 기준이 됩니다.)로 변경됩니다.
  4. Serializable (직렬화)
    • 특징
      • 가장 높은 격리 수준으로, 동시성을 완전히 차단하여 하나의 트랜잭션이 완전히 종료될 때까지 다른 트랜잭션은 해당 데이터에 접근할 수 없습니다.
      • 동시성 문제는 해결되지만, 성능이 저하될 수 있습니다.
      • 한 트랜잭션이 완전히 종료될 때까지 다른 트랜잭션은 해당 데이터에 접근할 수 없습니다.
    • 예시 결과
      1. 통장 잔액이 100달러인 상황에서 트랜잭션 A가 50달러를 출금합니다.
      2. 출금 중인 동안 트랜잭션 B가 통장 잔액을 읽어들입니다.
      3. Serializable 격리 수준에서는 출금과 입금이 직렬화되어 순차적으로 실행됩니다. 따라서, B는 A의 출금이 완료된 후에 입금을 진행합니다.
      4. A의 출금이 커밋되어 통장 잔액이 50달러로 변경됩니다.
      5. 이후, 트랜잭션 B가 30달러를 입금합니다.
      6. 트랜잭션 B의 입금이 커밋되어 통장 잔액이 80달러로 변경됩니다.

격리성 구분

 

이름 잔액
홍길동 1000
김국밥 500

 

  • Dirty Read (더티 리드)
    • 한 트랜잭션이 아직 커밋되지 않은 다른 트랜잭션의 변경된 데이터를 읽는 현상입니다.
    • 이로 인해 커밋되지 않은 데이터로 인해 일관성이 깨질 수 있습니다.
    • COMMIT 되지 않은 정보를 읽는다
    • 예)  트랜잭션1_(홍길동이 김국밥에게 900원 송금) / 트랜잭션2_(김국밥이 1400원 인출)
      • 트랜잭션1 송금(UPDATE) _ COMMIT 안됨 
      • 트랜잭션2 인출하기 위해 READ(READ)
      • 트랜잭션1 실패(ROLLBACK)
      •  트랜잭션1이 실패 하였으나 트랜잭션2는 송금된 금액 1400원을 읽었다.
  • Non-Repeatable Read (반복할 수 없는 읽기)
    • 한 트랜잭션이 같은 쿼리를 여러 번 실행할 때, 다른 트랜잭션이 중간에 해당 데이터를 변경하여 결과가 일관성 없이 읽는 현상
    • 하나의 트랜잭션에서 같은 데이터를 읽었지만 다른 데이터가 출력이 된다.
    • 예) 트랜잭션1_(홍길동이 잔고를 3번 읽는다) / 트랜잭션2_(김국밥이 홍길동이 2번 READ이후 200원 송금한게 COMMIT된다.)
      • 트랜잭션1 READ -> 1000원
      • 트랜잭션2 홍길동 에게 200원 송금(미 커밋)
      • 트랜잭션1 READ -> 1000원
      • 트랜잭션2 200원 송금 COMMIT
      • 트랜잭션1 READ -> 1200원
      • 같은 쿼리를 실행해도 하나의 트랜잭션에서 READ 데이터가 변경 되었다.
  • Phantom Read (유령 읽기)
    • 한 트랜잭션이 범위 검색 쿼리를 실행할 때, 다른 트랜잭션이 데이터를 삽입, 삭제하거나 변경하여 결과 ROW 가 변경되는 현상
    • 즉, 같은 범위 검색 쿼리를 여러 번 실행해도 결과 ROW 갯수가 달라질 수 있습니다.
    • 없던 데이터가 생겼다(NON_REPEATABLE_READ 와 비슷하나 변경된 ROW 데이터가 아니라 ROW가 추가되어 READ된다.)
    • 예) 트랜잭션1_(1000원 이상인 데이터를 2번 읽는다) / 트랜잭션2_(트랜잭션1이 1번 읽고 난뒤 김국밥에게 +700원 UPDATE한다.)
      • 트랜잭션1 "WHERE 잔액 >= 1000 READ" -> (홍길동) 출력
      • 트랜잭션2 김국밥에게 700원 송금(COMMIT 완료)
      • 트랜잭션1 "WHERE 잔액 >= 1000 READ" -> (홍길동, 김국밥) 출력
      • 같은 조건문으로 검색해도 결과 ROW 갯수가 달라 졌다.
  Dirty Read Non-Repeatable Read Phantom Read
Read Uncommitted O O O
Read Committed X O O
Repeatable Read X X O
Serializable X X X
728x90

'DB' 카테고리의 다른 글

데드락  (0) 2023.07.05
MySql DB 엔진  (0) 2023.07.03
Redis란?_Sorted sets  (0) 2023.04.16
Redis란?_Sets  (0) 2023.04.16
Redis 란?_Hash  (0) 2023.04.16