트랜잭션 격리

midas·2022년 6월 10일
0

1. 트랜잭션의 4가지 특징

원자성(Atomicity)

트랜잭션이 DB에 모두 반영되거나, 전혀 반영되지 않아야 되는 것을 뜻합니다.
(All or Nothing)

일관성(Consistency)

트랜잭션 작업 처리의 결과가 항상 일관되어야 합니다.

독립성(Isolation)

하나의 트랜잭션은 다른 트랜잭션에 끼어들 수 없으며 독립적임을 뜻합니다.

지속성(Durability)

트랜잭션이 성공적으로 완료되면 영구적으로 결과에 반영되어야 합니다.

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

트랜잭션의 격리 수준(isolation level)이란 여러 트랜잭션이 동시에 처리 될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 할지 말지를 결정하는 것입니다.

3. 격리수준 4가지 어떤게 있을까?

READ UNCOMMITTED

각 트랜잭션의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 조회 됩니다.

그림을 보면 둘리의 잔고는 0원이었다가 10,000원이 입금되어 UPDATE 되었습니다.
하지만 트랜잭션 B에서 커밋하기도 전에 둘리의 계좌를 검색하고 있습니다.
이 격리수준에서는 COMMIT되기 전에도 변경 상태를 조회할 수 있어 만약에 ROLLBACK이 된 경우에는 문제가 될수도 있습니다.

이처럼 트랜잭션에서 처리한 작업이 완료되지 않았음에도 다른 트랜잭션에서 볼 수 있는 현상을 Dirty Read라고 합니다.
그리고 이를 허용하는 격리 수준이 READ UNCOMMITTED 입니다.

READ COMMITTED

  • 커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회 가능
  • 오라클 DBMS에서 기본으로 사용되는 격리 수준
  • 트랜잭션에서 커밋이 안되어 있다면, 다른 트랜잭션에서 undo영역의 기존 값을 조회

트랜잭션 B가 처음에 조회했을 때는 트랜잭션 A가 COMMIT하기 전이었기 때문에 변경 결과가 적용되기 전인 0원으로 조회되는 것을 확인할 수 있습니다.
그리고 B의 두번째 조회에서는 COMMIT된 이후라서 변경 내용이 적용된 만원이 조회됩니다.
이는 트랜잭션에서 SELECT 쿼리를 실행했을 때는 항상 같은 결과를 가져와야 한다는 'REPEATABLE READ' 정합성에 어긋나게 됩니다.

REPEATABLE READ

  • 트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장
  • MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준
  • InnoDB 스토리지 엔진은 트랜잭션이 ROLLBACK 될 가능성이 대비해 변경되기 전,
    레코드를 undo 공간에 백업해두고 실제 레코드 값을 변경

두번의 SELECT 쿼리 결과는 똑같아야 합니다.
하지만 그림과 같이 트랜잭션의 수행한 변경 작업에 의해 레코드가 보였다 안 보였다 하는 현상을 PHANTOM REA라고 합니다.
SELECT ... FOR UPDATE 쿼리는 SELECT 하는 레코드에 쓰기 잠금을 걸어야 하는데, undo 레코드에는 잠금을 걸 수 없습니다.
그래서 undo 영역의 변경 전 데이터를 가져오는 것이 아니라 현재의 데이터 값을 가져오게 됩니다.

SERIALIZABLE

  • 한 트랜잭션에서 사용되는 데이터를 다른 트랜잭션에서 접근 불가
  • 가장 단순한 격리수준과 동시에 가장 엄격한 격리 수준

InnoDB 스토리지 엔진에서는 갭 락, 넥스트 키 락 덕분에 REPEATABLE REA 격리 수준에서도 이미 'PHANTOM READ'가 발생하지 않기 때문에 굳이 SERIALIZABL을 사용할 필요가 없다?

트랜잭션 격리 수준 비교

🔖 참고

profile
BackEnd 개발 일기

0개의 댓글