트랜잭션의 격리성(Transaction Isolation)

배경

트랜잭션의 성질(ACID)

  • 원자성 (Atomicity)

  • 일관성 (Consistency)

  • 격리성 (Isolation)

  • 영속성 (Durability)

격리성

  • 실행중인 트랜잭션의 중간결과를 다른 트랜잭션이 접근할 수 없음

    • 이때 접근 레벨이 존재함

      • 접근 레벨에 따라 다른 강도 설정

      • DB별로 설정 가능

격리성으로 인해 발생가능한 문제점

Dirty Read

  • 개념

    • 다른 트랜잭션에 의해 수정됐지만, 아직 커밋되지 않은 데이터를 읽는 것

  • 상황

    • 트랜잭션A가 정상처리 되지 않고 Rollback 될 수 있는데 트랜잭션B가 해당 값을 읽은 경우

      • 트랜잭션B는 잘못된 값을 가지고 본인의 로직을 처리하는 상태에 놓임

      • 즉, 트랜잭션B는 무결성이 깨진 데이터를 사용하게 됨

  • 특징

    • 지나친 부정합 문제 발생

      • 데이터가 조회되었다 사라지는 현상을 초래해 시스템에 상당한 혼란을 줌

      • RDBMS 표준에서 인정하지 않을 정도로 정합성에 문제가 많은 격리 수준

Non-Repeatable Read

  • 개념

    • 한 트랜잭션 내에서 같은 Key를 가진 Row를 두 번 읽었는데, 그 사이에 값이 변경되거나 삭제되어 결과가 다르게 나타나는 현상

  • 상황

    • 트랜잭션B가 특정 ROW에서 2번 READ 함

    • 이 사이에 트랜잭션A가 해당 ROW를 Update 혹은 Delete 후 Commit 함

    • 트랜잭션B가 다시 READ할때 값이 다르게 나옴

  • 특징

    • 일반적인 경우에는 크게 문제가 되지 않음

    • 금전적인 처리와 연결될 시 문제 발생 가능

Phantom Read

  • 개념

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

  • 상황

    • 트랜잭션B가 특정 조건을 데이터를 검색해 결과를 얻음 (트랜잭션B는 아직 끝나지 않은 상태)

    • 이때 트랜잭션A가 해당 조건의 일부를 추가/삭제하고 Commit 함

      • (아직 끝나지 않은)트랜잭션B가 해당 조건으로 데이터 조회 시, 트랜잭션A에서 추가/삭제한 데이터가 함께 조회/누락 됨

COMMIT : 트랜잭션을 종료하고 다른 사용자에게 변경된 모든 사항을 보이게 함.

Phantom Read와 Non-Repeatable Read Non-Repeatable Read, 한 개의 Row의 데이터 값이 변경되는 것(Update 또는 Delete) Phantom Read, 다수의 건을 요청하는 것에 대해 데이터의 값이 변경되는 것

트랜잭션의 격리 수준

  • 개념

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

  • DB에서 제공하는 격리성 수준

    • DBMS에 따라 내부적 격리성 제공

  • ANSI/ISO SQL 표준(SQL92)

    • 트랜잭션의 격리성과 동시 처리 성능 사이의 Trade-Off를 두고 격리성 접근 레벨을 4단계로 나눔

  • Trade-Off 관계

    • 높은 격리 수준

      • 높은 데이터 정합성: 격리성으로 인한 이슈 적게 발생

      • 낮은 동시 처리 성능

    • 낮은 격리 수준

      • 낮은 데이터 정합성

      • 높은 동시 처리 성능

  • LOCK

    • 트랜잭션 발생 시 DB 내부적으로 DB Lock이 걸림

트랜잭션 격리 단계

격리수준이 낮음 → 높음 순서로 진행

◻️ Read Uncommitted

  • 개념

    • 트랜잭션에서 처리 중인 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용

    • 커밋하지 않은 데이터 조차도 접근할 수 있는 격리 수준

  • 특징

    • 정합성의 문제로 권장하지 않음

  • 발생 가능 문제점

    • Dirty Read

    • Non-Repeatable Read

    • Phanton Read

◻️ Read Committed

  • 개념

    • 트랜잭션이 커밋되어 확정된 데이터만 다른 트랜잭션이 읽도록 허용

  • 특징

    • 커밋 되지 않은 데이터에 대해서는 실제 DB 데이터가 아닌 Undo 로그에 있는 이전 데이터를 가져옴

    • Dirty Read의 발생가능성 막음

    • 오라클의 기본 트랜잭션 격리 수준

  • 발생 가능 문제점

    • Non-Repeatable Read

    • Phanton Read

◻️ Repeatable Read

  • 개념

    • 트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장하는 트랜잭션 격리수준

    • MVCC를 이용해 한 트랜잭션 내에서 동일한 결과를 보장하지만, 새로운 레코드가 추가되는 경우 부정합 발생 가능

  • 특징

    • MySQL의 InnoDB 엔진의 기본 트랜잭션 격리 수준

    • 어떤 트랜잭션이 읽은 데이터를 다른 트랜잭션이 수정하더라도 동일한 결과를 반환할 것을 보장

      • 트랜잭션 번호를 참고하여 자신보다 먼저 실행된 트랜잭션의 데이터만을 조회

        • 테이블에 자신 이후에 실행된 트랜잭션의 데이터가 존재할 경우 UNDO로그 참고로 데이터 조회

    • 새로운 레코드의 추가까지는 막지 않음

  • 동작 방식

    1. 사용자B가 id=50인 레코드 조회 (트랜잭션B)

      • 테이블 값(조회 결과): MangKyu

    2. 사용자A가 id=50인 레코드 갱신(트랜잭션A, 아직 트랜잭션B 종료되지 않음)

      • MVCC를 통해 기존 데이터는 변경, 백업된 데이터는 UNDO 로그에 남음

      • 테이블 값(조회 결과): MinKyu

      • UNDO로그: MangKyu

    3. (트랜잭션B가 끝나지 않은 상태에서)사용자B가 다시 동일한 SELECT문 실행

      • UNDO로그(조회 결과): MangKyu

      • 수정된 트랜잭션A가 아닌 이전의 트랜잭션B의 값이 나옴

  • 발생 가능 문제점

    • Phanton Read

      • 일반적인 MySQL 조회에선 발생하지 않음

        • 새로운 레코드의 추가를 막지않아 발생 가능하나 MVCC 덕분에 일반적인 조회에선 발생하지 않음

      • UNDO로그가 아닌 테이블로부터 데이터를 가져올때 발생할 수 있으나 해당 케이스는 거의 존재하지 않음

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

  • 개념

    • 동시 접근을 허용하는 DB에서 동시성을 제어하기 위해 사용하는 방법 중 하나

    • 동일한 레코드에 대해 여러 버전의 데이터가 존재하는 것

      • 일반적인 RDBMS에서는 변경전 레코드를 UNDO영역에 백업해두어 변경 전, 후 데이터가 모두 존재

  • 특징

    • 트랜잭션이 롤백된 경우 데이터 복원 가능

    • 서로 다른 트랜잭션간 접근할 수 있는 데이터 세밀하게 제어

    • 트랜잭션 번호

      • 각각의 트랜잭션은 순차 증가하는 고유한 트랜잭션 번호 존재

      • 백업 레코드에 어느 트랜잭션에 의해 백업되었는지 트랜잭션 번호를 함께 저장

MySQL에서 Repeatable Read를 기본 격리수준으로 사용하는 이유

  • 격리 수준과 서버 처리 성능

    • SERIALIZABLE이 아니라면 격리 수준이 높다고 MySQL서버 처리 성능 개선 및 저하가 크게 발생하지 않음

    • 결국 UNDO로그를 통해 레코드를 참조하는 과정이 거의 동일하기 때문

  • REPEATABLE READ

    • READ COMMITTED보다 동시 처리 성능이 뛰어남

    • 갭 락을 통해 Phantom Read까지 거의 발생하지 않음

◻️ Serializable Read

  • 개념

    • 트랜잭션을 순차적으로 실행

  • 특징

    • 가장 엄격한 수준의 격리 수준

    • 어떠한 데이터 부정합 문제도 발생 X

      • 여러 트랜잭션이 동일한 레코드에 동시에 접근할 수 없음

    • 매우 낮은 동시 처리 성능

      • 트랜잭션이 순차적으로 처리되야 함

    가장 안전하나 가장 성능이 떨어지므로, 극단적으로 안전한 작업이 필요한 경우가 아니면 사용하지 않음

    • 순수한 SELECT 작업에서도 대상 레코드에 넥스트 키 락을 읽기 잠금(Shared lock)으로 건다.

Ref

트랜잭션 격리성 수준 [MySQL] 트랜잭션의 격리 수준(Isolation Level)에 대해 쉽고 완벽하게 이해하기

Last updated