트랜잭션 격리 수준

이상민·2021년 8월 22일
0
post-thumbnail

1. 트랜잭션 격리 수준이란?

동시에 여러 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용하는 수준

  • 격리 수준이 낮을수록 동시에 여러 사용자가 같은 데이터에 접근할 수 있어 성능이 높지만, 동기화 문제가 발생한다

  • 데이터베이스 수준에서 격리 수준이 정의된다

  • 트랜잭션의 ACID 특성에서 Isolation이 결정되는 부분이다

  • 트랜잭션 격리 수준을 이해하기 위해선 우선 3가지 읽기 이상 현상을 알아야한다


2. 3가지 읽기 이상 현상

트랜잭션 격리 수준을 통해 회피할 수 있는 3가지 현상들. 트랜잭션의 격리가 없다면 다음과 같은 상황들이 발생 가능하다

2-1. Dirty Reads

  • 트랜잭션 A가 데이터를 변경하고 커밋하기 이전에 트랜잭션 B가 해당 데이터를 읽는다면, 잘못된 데이터를 읽게 됨
-- 트랜잭션 A
UPDATE product price = 1000
WHERE productNo = 123

                              -- 트랜잭션 B (트랜잭션 A의 커밋 또는 롤백 이전에 실행)
                              SELECT * 
                              FROM product
                              WHERE productNo = 123

ROLLBACK;

2-2. Non-Repeatable Reads

  • 트랜잭션 A는 SELECT하는 구문이고, 트랜잭션 B는 데이터를 변경하는 구문일때, 트랜잭션 A는 B 때문에 반복 수행 시 다른 결과를 가져오게 된다
-- 트랜잭션 A
SELECT * 
FROM product
WHERE productNo = 123

                            -- 트랜잭션 B
                            UPDATE PRODUCT PRICE = 1000
                            WHERE productNo = 123
                            COMMIT;

SELECT * 
FROM product
WHERE productNo = 123
COMMIT;

2-3. Phantom Reads

  • Non-Repeatable Reads와 유사하지만 새로운 레코드가 추가되거나 삭제되어 발생한다
-- 트랜잭션 A
SELECT * 
FROM product
WHERE price >2000

                      -- 트랜잭션 B
                      INSERT INTO product (id, price)
                      VALUES (123, 3000)
                      COMMIT;

SELECT * 
FROM product
WHERE price > 2000
COMMIT;

3. 트랜잭션 격리 수준

3-1. TRANSACTION_READ_UNCOMMITTED

  • 트랜잭션이 커밋되지 않은 데이터를 읽을 수 있음

  • Dirty Reads, Non-Repeatable Reads, Phantom Reads가 모두 발생 가능

3-2. TRANSACTION_READ_COMMITTED

  • 트랜잭션은 커밋된 데이터만 읽을 수 있음

  • 락 기반 병행성 구현 데이터베이스에선 쓰기 락을 트랜잭션 종료까지 유지한다

  • Dirty Reads는 없지만 읽기 락을 유지하지 않기 때문에 Non-Repeatable Reads와 Phantom Reads는 여전히 발생

3-3. TRANSACTION_REPEATABLE_READ

  • 락 기반 병행성 구현 데이터베이스에선 읽기와 쓰기 락을 트랜잭션 종료까지 유지한다

  • Dirty Reads와 Non-Repeatable Reads 문제는 회피하지만 범위 락을 관리 하지 않아 Phantom Reads는 발생 가능

3-4. TRANSACTION_SERIALIZABLE

  • 가장 엄격한 트랜잭션 격리 수준

  • 락 기반 병행성 구현 데이터베이스에선 읽기 쓰기 락을 트랜잭션 종료까지 유지하고 범위 SELECT에 대해 락을 설정한다


4. 트랜잭션 격리 수준에 따른 성능

  • ACID 특성 중, Isolation은 가장 느슨하게 지켜지는 특성 중 하나이다. 완전한 Isolation을 하려면, 모든 연산마다 데이터에 락을 걸어야하고 그러면 병행성을 잃게된다

  • 따라서 필요한 격리 수준을 제약조건으로 가지고, 가장 느슨한 수준을 선택해 성능과 격리 수준의 사이에서 선택해야한다

  • 참고로 MySQL의 기본 트랜잭션 격리 수준은 REPEATABLE READ이고 PostgreSQL의 기본 격리 수준은 READ COMMITTED이다


참고

https://en.wikipedia.org/wiki/Isolation_(database_systems)

profile
편하게 읽기 좋은 단위의 포스트를 추구하는 개발자입니다

0개의 댓글