트랜잭션 격리 수준(Transaction Isolation Level)

Hyeok·2023년 4월 13일
0

CS

목록 보기
12/12

트랜잭션 격리 수준(Transaction Isolation Level)

트랜잭션 격리수준이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것입니다. 즉, 간단하게 말해 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것입니다.

  • 격리수준은 4개로 분류된다
  1. READ UNCOMMITTED
  2. READ COMMITTED
  3. REPEATABLE READ
  4. SERIALIZABLE

-> 하나하나 알아보자

1. READ UNCOMMITTED

  • READ UNCOMMITTED는 격리수준에서는 어떤 트랜잭션 변경 내용이 COMMIT이나 ROLLBACK과 상관없이 다른 트랜잭션에서 보여집니다.
    아래와 같은 문제가 발생할 수 있다.


  1. A 트랜잭션에서 테이블의 데이터를 수정 중인 상태이고 아직 커밋하지 않았습니다.

  2. B 트랜잭션에서 A 트랜잭션이 수정 중인 데이터를 조회 함. 이를 Dirty Read라고 합니다.

  3. B 트랜잭션은 커밋되지 않은 데이터를 바라보고 로직을 수행함.

  4. A 트랜잭션에서 문제가 발생해 ROLLBACK 함

    데이터 정합성에 문제가 많아, RDBMS 표준에서는 격리수준으로 인정 X


2.READ COMMITTED

어떤 트랜잭션의 변경 내용이 COMMIT 되어야만 다른 트랜잭션에서 조회할 수 있습니다. 오라클 DBMS에서 기본적으로 사용하고 있고, 온라인 서비스에서 가장 많이 선택되는 격리수준입니다.

여기서는 B 트랜잭션에서 A 트랜잭션에서 커밋이나 롤백하기전까지는 DIRTY READ가 발생하지 않습니다. (UNDO 영역에 저장된 데이터를 참조)

언뜻보면 정합성 문제가 해결된 것 처럼 보이지만, 여기서도 NON-REPEATABLE READ 부정합 문제가 발생할 수 있습니다.

Ex)
1. A 트랜잭션에서 8번 상품의 총 투자 공모금액을 조회
2. 10만원 조회
3. B 트랜잭션에서 8번의 총 투자공모금액을 20만원으로 바꾸고 커밋
4. B 트랜잭션에서 8번의 총투자금액 조회 20만원으로 조회된다.

이는 하나의 트랜잭션내에서 동일한 SELECT를 수행했을 경우 항상 같은 결과를 반환해야하는 REPEATABLE READ 정합성에 어긋나는 것입니다.

일반적인 웹 어플리케이션에서는 크게 문제되지 않지만, 작업이 금전적인 처리와 연결되어 있다면 문제가 발생할 수 있습니다.

예를 들어 트랜잭션에서 입금/출금 처리가 계속 진행되는 트랜잭션들이 있고, 오늘의 입금 총 합을 보여주는 트랜잭션이 있다고 하면, 총합을 계산하는 SELECT 쿼리는 실행될 때 마다 다른 결과 값을 가져올 것입니다.

이런 문제가 발생할 수 있기 때문에 격리수준에 의해 실행되는 SQL 문장이 어떤 결과를 출력할 지 정확히 예측하고 있어야 합니다.


3. REPEATABLE READ

REPEATABLE READ 격리수준은 간단하게 말해서 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리수준입니다.

MYSQL DMBS에서 기본적으로 사용하고 있고, 이 격리수준에서는 NON-REPEATABLE READ 부정합이 발생하지 않습니다.

Ex)
1. 3번 트랜잭션이 1번 상품을 조회
2. 9번 트랜잭션이 1번 상품의 총 투자공모금액을 변경하고 커밋
3. 3번 트랜잭션이 1번 상품을 다시 조회
4. 언두 영역에 백업된 데이터 반환

즉, 자신의 트랜잭션 번호보다 낮은 트랜잭션 번호에서 변경된(+커밋된)것만 보게 되는 것입니다.

  • 언두영역이란?
    (UPDATE 문장이나 DELETE 문장으로 데이터를 변경했을 때 변경되기 전의 데이터(이전 데이터)를 보관하는 곳)

4.Phantom READ

한 트랜잭션 내에서 같은 쿼리를 두 번 실행했는데, 첫 번째 쿼리에서 없던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상을 말합니다.

REPEATABLE READ 이하에서서만 발생하고(SERIALIZABLE은 발생하지 않음), INSERT에 대해서만 발생합니다.


5.SERIALIZABLE

가장 단순하고 가장 엄격한 격리수준입니다.
InnoDB에서 기본적으로 순순한 SELECT 작업은 아무런 잠금을 걸지않고 동작하는데, 격리수준이 SERIALIZABLE일 경우 읽기 작업에도 공유 잠금을 설정하게 되고, 이러면 동시에 다른 트랜잭션에서 이 레코드를 변경하지 못하게 됩니다.

-> 이러한 특성 때문에 동시처리 능력이 다른 격리수준보다 떨어지고, 성능저하가 발생하게 됩니다


profile
안녕하세요.

4개의 댓글

comment-user-thumbnail
2023년 4월 13일

트랜잭션 엄격도에 따라 설명이 돼있어서 좋았습니다.

답글 달기
comment-user-thumbnail
2023년 4월 13일

트랜잭션 격리수준 각 종류마다 특징을 잘 정리해주셔서 이해하기 편했던거 같습니다.

답글 달기
comment-user-thumbnail
2023년 4월 13일

유형에 따라 분류도 잘해주시고 예시를 자세하게 들어주셔서 이해하기 편했습니다 ! 👍

답글 달기
comment-user-thumbnail
2023년 4월 14일

트랜잭션 격리수준에 대한 내용을 처음 접했는데 이해하기 쉬워 좋았습니다.

답글 달기