Transaction Isolation level

김태준·2023년 2월 17일
0

DB STUDY

목록 보기
9/17
post-thumbnail

DB, SQL 스터디를 시작한지 벌써 2달째
최대한 매주 1회 모여 서로 학습한 내용을 공유하거나 문제 풀이 코드를 공유하며 스터디를 진행 중이다!

이번 주차에는 트랜잭션 격리 수준에 대해 학습해보려 한다.
격리 수준에 앞서 격리성에 대해 알아보려 한다.
https://zzang9ha.tistory.com/381
위 작성자 분이 깔끔하게 정리해주신 덕분에 내용 이해가 수월했습니다!

✅ Transaction

데이터의 정합성을 보장하기 위한 기능
논리적인 작업 자체가 ALL(commit) OR NOTHING(ROLLBACK)을 보장하는 것
Atomicity, Consistency, Isolation, Durability를 보장해야 함.

✅ Transaction Isolation

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

1. 활동 : 트랜잭션이 실행 중인 상태(연산들 정상 작동)
2. 부분완료 : COMMIT 연산 실행 전 상태로 작성된 것들을 저장하지 않은 상태
3. 실패 : 트랜잭션 실행 중 오류가 발생해 중단된 상태
4. 완료 : 트랜잭션이 성공적으로 종료되어 COMMIT 실행 이후의 상태
5. 철회 : 트랜잭션이 비정상적으로 종료되어 ROLLBACK 연산을 수행한 상태

  • COMMIT : 변경된 데이터를 테이블에 영구적으로 반영하는 것
    1) COMMIT 이전 단지 메모리 버퍼에만 영향을 받았기에 데이터 변경 이전 상태로 복구 가능
    2) 현 사용자는 SELECT문으로 결과 확인 가능
    3) COMMIT 이전 타인이 현 사용자가 수행한 결과 볼 수 없다.
    4) COMMIT 이전 변경된 행은 LOCKING 설정으로 인해 타 사용자가 변경 불가능
    5) 어플리케이션 정상 종료 or 이상으로 인해 종료로 DB 접속 단절된 경우 자동 ROLLBACK
  • ROLLBACK : 작업 중 문제 발생 시 트랜잭션 처리과정에서 발생한 변경사항 취소
    COMMIT 이전 데이터에 대해 변경 사항이 있으면 취소가 가능한데 이를 DB에서 ROLLBACK 기능을 통해 사용할 수 있다. ROLLBACK은 데이터 변경 사항이 취소 되어 이전 상태로 복구되며 관련된 ROW에 대해 LOCKING이 풀리고 타인이 데이터 변경에 대한 접근 권한을 갖게 된다.

✍️ Transaction Isolation level

🎈 1. READ UNCOMMITTED

  • 각 트랜잭션의 변경 내용이 COMMIT, ROLLBACK 여부에 상관없이 타 트랜잭션에서 값 읽기 가능
    정합성에 문제가 많고 가장 낮은 수준의 격리이기에 사용하지 않는 것을 권장
  • 아래 그림과 같이 COMMIT이 되지 않는 상태이지만, 타 사용자로 인해 변경된 값을 다른 사용자가 읽을 수 있음

    발생하는 문제는 없는가?
    DIRTY READ 발생 : 트랜잭션 작업 완료가 아닌 상태인데도 타 트랜잭션에서 볼 수 있는 상황

🎈 2. READ COMMITED

  • RDB(오라클 DBMS)에서 대부분 기본적으로 사용되는 격리 수준 (최소 보장해야 하는 격리 수준)
  • DIRTY READ 현상 발생 X (commit이 완료된 데이터만 조회 가능)
  • 실제 테이블 값을 가져오는 것이 아니고 UNDO 영역에 백업된 레코드에서 값을 가져옴
    (REDO : 복구 시 사용자가 했던 작업 반복 / UNDO : 사용자가 했던 작업 반대로 진행해 복구)
    UNDO 영역의 데이터를 가져오며 격리 수준 유지, 높은 동시성 제공 가능

    발생하는 문제는 없는가?
    트랜잭션 1이 COMMINT 연산을 실행한 이후, 아직 끝나지 않은 상황에서 트랜잭션 2가 다시 테이블 값을 읽으면 변경될 수 있다.
    결국, NON-REPEATABLE READ라는 문제 발생 (하나의 트랜잭션 내 동일한 SELECT 쿼리 실행 시 항상 같은 결과가 아닌 경우)
    이는 은행과 같은 금융 산업에 있어 정합성이 깨지는 문제는 큰 위험

🎈 3. REPEATABLE READ

  • MySQL InnoDB 스토리지 엔진에서 기본적으로 사용되는 격리수준
  • MySQL은 트랜잭션마다 고유 ID를 부여해 트랜잭션 ID보다 작은 번호만 변경한 것 읽게 함 (변경된 ID가 트랜잭션 ID보다 크다면 UNDO 공간에 백업한 내용 읽게 됨을 의미)
  • UNDO 공간에 백업해두고 실제 레코드 값 변경
    (백업 데이터는 불필요하다고 판단한 시점에 주기적으로 삭제, 백업된 레코드 양 많을수록 MySQL 서버처리 성능 악화)
  • MVCC(Multi Version Concurrency Control)이라 부름

    발생하는 문제는 없는가?
    Update 연산의 경우 메모리 문제가 발생하지 않고, DELETE, INSERT에 한해 메모리 문제가 발생하므로 UNDO영역에 크기가 커지는 문제가 발생할 수 있다.
    PHANTOM READ : 타 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다 안보였다하는 현상
    -> 이를 방지하기 위해 쓰기 잠금을 걸어야 함
  • 추가 사항

❗Repeatable read에서 PHANTOM READ가 발생하는 이유

: A 트랜잭션이 USER라는 테이블에서 사용자 NAME이 SON인 경우를 SELECT하는 하고 B 트랜잭션이 NAME을 KANE으로 바꾸고 COMMIT했다. 이후 A트랜잭션이 이름이 SON인 사람의 이름을 SUN으로 바꾸고자 하는 경우라고 가정해보자.

이 상황에서는 최종 결과로 NAME은 KANE이 되고 B트랜잭션에서 이름을 바꾼 후 COMMIT했으므로, UNDO영역에 기존 이름 SON의 내용이 있어야 A트랜잭션이 일관성을 보장받을 수 있다.
이후 A트랜잭션에서 UPDATE를 진행할 때 베타 lock이 필요한데 A트랜잭션이 바라보는 영역은 UNDO이므로, UNDO에 대해서는 베타 lock을 걸 수 없다.

그러므로 UPDATE 구문에서 베타 락을 시도하지만, name이 son인 레코드가 존재하지 않으므로 아무 일도 일어나지 않아 A트랜잭션의 실행으로 인한 UPDATE결과가 반영되지 않고 두 트랜잭션 사이에 데이터 부정합이 발생하게 된다.

🎈 4. SERIALIZABLE

  • 가장 단순한 격리 수준이자 가장 엄격한 격리 수준
  • 성능 측면에서 동시 처리성능이 가장 낮다
  • PHANTOM READ 현상 발생 X BUT, DB에선 거의 사용되지 않는다.
  • 트랜잭션 격리 수준이 해당 격리수준으로 설정되면 읽기 작업도 공유 잠금을 획득해야 해 동시성이 떨어지게 된다.

💯 정리하면 다음과 같다.

READ UNCOMMITED : 트랜잭션 내에서 COMMIT 하지 않은 데이터에 대해 타 사용자가 접근 가능
READ COMMITED : 트랜잭션 내에서 COMMIT 된 데이터만 타 사용자가 접근 가능
REPEATABLE READ : 트랜잭션 내에서 한 번 조회한 데이터를 반복해서 조회해도 결과는 동일
SERIALIZABLE : 가장 엄격한 격리 수준으로 접근 권한 부여를 통해 완벽한 읽기 일관성 모드 제공

❗ 발생할 수 있는 문제점

DIRTY READ : 트랜잭션 A에서 처리한 작업이 완료되지 않았음에도 타 트랜잭션에서 볼 수 있는 현상
NON-REPEATABLE READ : 동일한 SELECT 쿼리 실행시 항상 결과가 같지 않아 정합성 보장 X(Update)
PHANTOM READ : 하나의 트랜잭션에서 동일한 쿼리를 두번 실행해 결과가 다른 PHANTOM 레코드가 나타나는 현상(Insert)

profile
To be a DataScientist

0개의 댓글