트랜잭션 ACID 특성과 Isolation Level

김범준
직방 기술 블로그
6 min readOct 13, 2022

--

안녕하세요! BE 직방부동산팀에서 근무중인 Jeff 입니다. 이번 포스팅에서는 기술면접의 단골 질문인 트랜잭션의 ACID 특성과 격리 수준 (Isolation Level)에 대해 알아보려 합니다. 그럼 시작해 볼까요?

1. 트랜잭션(Transaction) 이란?

트랜잭션은 한 번에 처리 되어야 할 하나 또는 둘 이상의 처리 작업의 모음으로 DBMS에서 실행되는 논리적 작업 단위라 할 수 있습니다.

이러한 트랜잭션의 안전한 실행을 보장하기 위해 4가지의 특성(성질)을 가지고 있습니다. 우리가 학부 시절 많이 배웠던 ACID 인데요 정리하면 다음과 같습니다

1) A (Atomicity, 원자성)

  • 개념: 트랜잭션의 연산 전체가 처리 되거나 되지 않아야 함
  • 보장기법: rollback, commit, transaction begin, end

2) C (Consistency, 일관성)

  • 개념: 트랜잭션 실행 완료 후 언제나 일관성 있는 DB상태를 보존해야 함
  • 보장기법: 도메인, 관계 무결성 처리 (ex: not null, foreign key, check, unique key 등)

3) I (Isolation, 고립성)

  • 개념: 트랜잭션 실행 시 다른 트랜잭션의 연산이 끼어들지 못하도록 함
  • 보장기법: Locking (2 Phase Locking), Timestamp Ordering, MVCC, Isolation Level

4) D (Durability, 영속성)

  • 개념: 성공이 완료된 트랜잭션의 결과는 영구적으로 DBMS에 저장되어야 함
  • 보장기법: DBMS 회복 (ex: redo, undo, 로그기반, 체크리스트 회복 등)

2. 트랜잭션의 직렬성

동시에 많은 작업을 받는 DBMS에서는 각 트랜잭션이 영향없이 순서대로 하나씩 차례대로 수행될 수 있도록 보장해야 합니다.

직렬성이란 위 처럼 동시성을 가진 작업들을 얼마나 잘 처리할 수 있는지에 대한 성질이며 만약 직렬성을 보장할 수 없다면 다음과 같은 문제들이 발생하게 됩니다.

(설명을 위해 다음과 같은 테이블이 있다고 가정하겠습니다.)

(가상의) 사원 테이블

1) Dirty Read

Dirty Read는 아래 그림과 같이 아직 commit 되지 않은 불확실한 데이터를 읽게 됨으로 일관성을 유지하지 못하는 문제 입니다.

dirty read 예시

결과적으로 사번이 4번인 “이순신"은 사원 테이블에 적재되지 못했음에도 Transaction B가 해당 값을 읽어 사용하고 있는 문제가 발생합니다.

2) Non-Repeatable Read

Non-Repeatable Read 는 한트랜잭션에서 동일한 쿼리를 수행했을 때 결과가 다르게 나오는 문제입니다.

Non-Repeatable Read 예시

Transaction A가 첫번 째 사번:3 사원을 읽었을 때 부서가 마케팅이지만 두번 째 쿼리에서는 “디자인"으로 출력되는 문제가 발생합니다. Transaction B에 의해 값이 변경되었기 때문입니다.

3) Phantom Read

Phantom Read 는 한트랜잭션에서 동일한 쿼리를 수행했을 때 첫 번째 쿼리에서 없던 결과가 나타나는 문제입니다.

Phantom Read 예시

Transaction A가 첫번 째 쿼리에서 부서가 개발인 사원을 모두 읽어올 때 결과는 홍길동 하나 뿐이지만 두번 째 쿼리에서는 김직방이 추가로 출력되는 문제가 발생합니다. Transaction B에 의해 사번:3 김직방의 부서가 개발로 변경되었기 때문입니다.

3. 트랜잭션의 Isolation Level (격리수준)

위와 같은 문제들은 트랜잭션의 동시성의 문제로 발생합니다. 동시성과 일관성은 서로 위배되는 조건으로 Trade Off의 성격을 가지고 있으며, DBMS에서는 일관성과 동시성을 적절하게 조합하여 사용할 수 있도록 Isolation Level을 제공합니다.

일관성과 동시성의 Trade Off

Isolation Level은 총 4단계로 구분할 수 있으며 다음과 같습니다.

1) Read Uncommitted

  • 개념: 트랜잭션이 처리중인 commit 되지 않은 데이터를 다른 트랜잭션이 읽도록 허용 하는 레벨
  • 레벨: 0
  • 발생가능 문제: Dirty Read, Non-Repeatable Read, Phantom Read

2) Read Committed

  • 개념: 트랜잭션이 commit 되어 확정된 데이터만 다른 트랜잭션이 읽도록 허용 하는 레벨
  • 레벨: 1
  • 발생가능 문제: Non-Repeatable Read, Phantom Read

3) Repeatable Read

  • 개념: 트랜잭션 내에서 동일 쿼리 두 번 이상 수행 시 첫 번째 쿼리의 레코드가 사라지거나 변경됨을 방지하는 레벨
  • 레벨: 2
  • 발생가능 문제: Phantom Read

4) Serializable Read

  • 개념: 트랜잭션 내에서 동일 쿼리 두 번 이상 수행 시 첫 번째 쿼리의 레코드가 사라지거나 변경됨을 방지하고 새로운 레코드가 나타나지 않도록 하는 레벨 (비 현실적인 옵션)
  • 레벨: 3
  • 발생가능 문제: 없음

위와 같은 4가지 격리 수준중 어떤 레벨을 사용할지 DBMS에 설정하여 동시성을 우선할지 일관성을 우선할지 선택할 수 있습니다.

참고) Isolation Level은 ISO에서 정한 분류 기준일 뿐 모든 DBMS가 공통적으로 지원하는 옵션은 아닙니다.

이상으로 트랜잭션의 ACID와 Isolation Level 에 대해 알아보았습니다.

--

--