ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 트랜잭션의 격리 수준 이라는 등가교환
    DB 2023. 8. 4. 20:41
    test

    MVCC

    RDBMS를 구현하기 위한 개념으로 ACID, Locking, Recovery 등 이 나왔지만

    동시성 제어 문제가 발생하였고 이를 해결하기 위해 잠금을 통한 상호배제를 사용했었는데

    상호배제로 인해 대기현상이 발생하여 DBMS의 동시성이 낮아지게 되었다

     

    💡 동시성 제어 문제는 대표적으로 Dirty read, Non-repeatable read, Phantom read 등이 있다.

     

    이러한 상호배제로 인해 낮아진 동시성문제를 해결하기 위해 읽기와 쓰기의 결합을 최소화할 수 있는 방법이 나오게 되었는데

    그게 바로

    동시에 발생하는 트랜잭션 속에서 데이터베이스에 저장된 데이터의 일관성과 격리성을 지킬 수 있도록 도와주는

    다중 버전 동시성 제어(MVCC)이다.

     

    MVCC는 SCN이라는 메커니즘을 사용하여 번호 값을 이용하여 트랜잭션 순서를 보장하는 특징이 있기에

    특정 시점을 기준으로 commit 된 데이터를 읽을 수 있다

     

    MVCC는 DMBS의 동시성을 위해 

    '특정 시점'을 통해 ACID 원칙을 다소 희생하여 동시에 실행되는 트랜잭션들이 어디까지 서로에게 영향을 미치지 않을지 정할 수 있는데

    그것이 바로 transaction isolation level이다

     

    • READ UNCOMMITTED(커밋되지 않은 읽기)
    • READ COMMITTED(커밋된 읽기)
    • REPEATABLE READ(반복 가능한 읽기)
    • SERIALIZABLE(직렬화 가능)

    READ UNCOMMITTED 가 제일 낮은 격리를 제공하고

    SERIALIZABLE 가 제일 강한 격리를 제공한다

     

    격리 수준에 따라 해결되는 동시성 문제 가있다.

    동시성 문제를 해결할수록, 즉 격리 수준을 엄격하게 가져갈 경우 동시성이 낮아지며

    동시성 문제를 어느 정도 수용할 경우, 즉 격리 수준을 느슨하게 가져갈 경우 동시성이 좋아진다.

     

    💡 트랜잭션 은 ACID 원칙을 보장해야 한다
    Atomicity(원자성): 작업이 부분적으로 성공하는 일이 없어야 한다
    Consistency(일관성): 일관성 있는 데이터 상태를 유지한다
    Isolation(독립성): 완료되지 않은 작업에 다른 트랜잭션이 끼어들지 못하게 한다
    Durability(영구성): 트랜잭션의 결과가 영구적으로 남아야 한다

     

    READ UNCOMMITTED

    커밋되지 않은 데이터에 접근 가능한 격리 수준이다.

    사실 어떠한 독립성도 없기에 격리 수준이라 부를 수 없다.

     

     

    Dirty read 발생

    A 트랜잭션이 데이터를 변경하거나 추가하고 commit 하기 전에

    B 트랜잭션이 해당 데이터를 읽을 때 읽어지는 문제인 dirty read 가 발생한다

    예로 아래와 같은 문제가 발생할 수 있다

     

    1. A 트랜잭션이 유저의 이름을 “Alice” 에서 “bob” 으로 변경하고 커밋하지 않은 상태에서
      B 트랜잭션이 데이터를 읽을 때 “bob”이라 읽게 됨
    2. A 트랜잭션이 “Alice” 이름을 가진 유저를 추가하고 커밋하지 않은 상태에서
      B 트랜잭션이 “Alice” 유저를 읽어서 다른 로직을 수행 중인데 A 트랜잭션이 롤백.

    READ COMMITTED

    트랜잭션의 변경 내용이 commit 되어야만 다른 트랜잭션에서 조회가능한 격리 수준

    오라클 DBMS에서는 기본으로 사용 중이며 가장 많이 선택되는 격리 수준이다.

     

     

    1. A 트랜잭션이 유저의 “Alice”이라는 이름을 “bob” 으로 변경하고 커밋하지 않은 상태에서
      B 트랜잭션이 데이터를 읽을 때는 “Alice”이라 읽게 된다.(”Alice” 데이터는 MVCC 영역에 있다)

    NON-REPETABLE READ 발생

    하나의 트랜잭션에서 같은 값을 조회할 때 다른 값이 조회되는 문제이다.

     

    1. A 트랜잭션이 유저를 조회하니 “Alice”이라 조회됨
    2. B 트랜잭션이 “홍길동” 유저를 조회하여 “bob” 으로 이름을 변경하고 커밋
    3. A 트랜잭션이 유저를 조회하니 “bob”이라 조회됨

    이는 하나의 트랜잭션 내에서는 똑같은 SELECT 수행 시 같은 결과를 반환해야 한다는 REPETABLE READ 정합성이 어긋한 것.

    REPETABLE READ

    MySQL InnoDB 스토리지 엔진의 기본 격리 수준이다

    트랜잭션이 시작되고 종료되기까지 한번 조회한 값은 계속 같은 값이 조회되는 격리 수준이다.

     

     

    1. A 트랜잭션이 유저를 조회하니 “Alice”이라 조회됨
    2. B 트랜잭션이 “Alice” 유저를 조회하여 “bob” 으로 이름을 변경하고 커밋
    3. A 트랜잭션이 유저를 조회하니 “Alice”이라 조회됨(MVCC 영역)

    이 방법은 자신의 트랜잭션 번호보다 낮은 트랜잭션 번호에서 변경된 내용만 확인하는 방법이다

    Phantom Read 발생

    REPETABLE READ는 다른 트랜젝션이 update 한 경우에도 변경 전 데이터를 조회할 수 있지만

    insert/delete 시에는 영향을 받는 문제가 발생한다.

    한 트랜잭션에서 같은 조건으로 데이터를 반복해서 읽었는데

    그 사이 다른 트랜잭션이 데이터를 추가해서 처음에는 없었던 데이터가 추가가 되거나

    반대로 있었던 데이터가 없어진 상태로 반환하는

    즉 다른 트랜잭션의 변경 작업에 의해 데이터가 보였다 안 보이는 문제이다

     

    1. A 트랜잭션이 N 개의 유저를 조회
    2. B 트랜잭션이 유저 추가
    3. A 트랜잭션이 N 개의 유저를 조회했더니 데이터가 하나 더 보임

    Serializable

    가장 단순하며 가장 엄격한 격리 수준이다

    트랜잭션이 특정 테이블을 읽으면 다른 트랜잭션에서 데이터를 추가, 변경, 삭제할 수 없다.

     

     

    참고

    https://medium.com/monday-9-pm/mvcc-multi-version-concurrency-control-알아보기-e4102cd97e59

    https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html

    https://joont92.github.io/db/트랜잭션-격리-수준-isolation-level/

     

    'DB' 카테고리의 다른 글

    Mysql(Maraidb) 실행 계획 살펴보기  (0) 2023.11.12
    db column명은 snake_case 가 최고다  (0) 2023.08.02
    FlyWay로 DB 형상 관리  (0) 2023.06.15