ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MariaDB Isolation
    Database 2023. 4. 1. 14:34

    Isolation Level

    1. READ UNCOMMITTED
      이 격리 레벨에서는 커밋되지 않은 데이터에 대한 읽기 작업도 허용됩니다. 따라서 다른 트랜잭션에서 변경 작업을 수행하는 동안, 해당 데이터에 대한 읽기 작업을 수행하면 변경 작업의 결과를 볼 수 있습니다. 이러한 이유로 이 격리 레벨은 데이터 일관성과 무결성이 보장되지 않으므로 사용하지 않는 것이 좋습니다.
    2. READ COMMITTED
      이 격리 레벨에서는 커밋된 데이터만 읽을 수 있습니다. 따라서 다른 트랜잭션에서 변경 작업을 수행하는 동안, 해당 데이터에 대한 읽기 작업을 수행하면 변경 작업의 결과를 볼 수 없습니다. 이 격리 레벨은 데이터 일관성과 무결성을 보장하면서도, 동시성을 높일 수 있어서 가장 많이 사용되는 격리 레벨 중 하나입니다.
    3. REPEATABLE READ
      이 격리 레벨에서는 한 트랜잭션 내에서 같은 쿼리를 실행하는 경우, 항상 동일한 결과를 반환합니다. 따라서 다른 트랜잭션이 데이터를 변경하더라도, 해당 트랜잭션에서는 변경된 데이터를 읽지 않습니다. 이러한 이유로 이 격리 레벨은 데이터 일관성과 무결성을 보장하면서도, 응답 시간을 높일 수 있습니다.
    4. SERIALIZABLE
      이 격리 레벨에서는 트랜잭션들이 서로 영향을 끼치지 않도록 모든 데이터에 대한 LOCK을 적용합니다. 따라서 동시성은 낮아지지만 데이터 일관성과 무결성을 가장 완벽하게 보장할 수 있습니다. 이러한 이유로 이 격리 레벨은 데이터 일관성과 무결성이 매우 중요한 상황에서 사용됩니다.

    READ COMMITTED와 REPEATABLE READ 테스트

    격리레벨에 따라서 트랜잭션 내에 조회 한 데이터가 어떤 결과를 가지고 오는지
    가장 많이 사용하는 격리레벨인
    READ COMMITTED와 REPEATABLE READ에서 테스트 해보겠습니다.

    READ COMMITTED 테스트

    다른 트랜잭션에서 커밋한 내용을 읽어 오는지 확인해 보겠습니다.

    -- T1
    BEGIN;
    SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey
    
    -- T2
    BEGIN;
    UPDATE users
    SET first_name = 'Kelsey2'
    WHERE id = 1;
    commit;
    
    SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey2
    
    -- T1
    -- SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey2
    
    -- 아직 T1이 종료되지 않은 상태인데 T2에서 Commit한 변경사항을 T1에서 불러옵니다.
    -- 이렇게 되면, 하나의 트랜잭션내에서 동일한 쿼리를 실행 했을 때
    -- 어느 순간 조회하느냐에 따라 다른 값을 불러올수 있게 됩니다.

    REPEATABLE READ 테스트1

    다른 트랜잭션에서 커밋한 내용이 반영되는지,
    동일한 쿼리가 동일한 결과를 반환하는지 확인해 보겠습니다.

    -- T1
    BEGIN;
    SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey
    
    -- T2
    BEGIN;
    UPDATE users
    SET first_name = 'Kelsey2'
    WHERE id = 1;
    commit;
    
    SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey2
    
    -- T1
    SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey
    
    -- REPEATABLE READ는 하나의 트랜잭션내에서 하나의 쿼리를 실행할 때 동일한 결과를 반환합니다.
    -- 그렇기 때문에 T2에서 first_name을 Kelsey2로 바꿨지만,
    -- T1이 처음 실행했던 쿼리 결과인 Kelsey 를 반환하게 됩니다.

    REPEATABLE READ 테스트2

    여기서 한번, 색다르게 테스트 해보겠습니다.
    트랜잭션만 시작하고 한번도 쿼리하지 않은 경우
    다른 트랜잭션 내에서의 커밋한 내용이 반영되는지 보시겠습니다.

    -- 현재 id = 1의 first_name 값 Kelsey
    -- T1
    BEGIN;
    
    -- T2
    BEGIN;
    UPDATE users
    SET first_name = 'Kelsey2'
    WHERE id = 1;
    commit;
    
    SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey2
    
    -- T1
    SELECT first_name FROM users WHERE id = 1 ;
    -- 결과 : Kelsey2
    
    -- T1을 시작할 때 id = 1의 first_name 값은 Kelsey 였습니다.
    -- 이후, T2에서 Kelsey2로 변경사항을 commit하게 되면,
    -- T1은 Kelsey가 아닌 T2에서 변경한 값 Kelsey2로 결과를 반환하게 됩니다.
    
    -- 이유는 한 트랜잭션 내에서 같은 쿼리를 실행하는 경우, 항상 동일한 결과를 반환할 뿐이지,
    -- 트랜잭셔 시작 시 한번도 쿼리하지 않은 결과를 가지고 있는 것은 아니기 때문입니다.

    'Database' 카테고리의 다른 글

    Phantom Rows  (0) 2024.08.06
    MariaDB Lock(이론)  (0) 2023.04.01
    MariaDB Lock(실전)  (0) 2023.04.01
    MariaDB Index 1편  (0) 2023.03.20
    HikariCP 설정 일부분 들여다 보기  (0) 2023.02.26

    댓글

Designed by Tistory.