Search

트랜잭션 격리 수준

카테고리
백엔드 🧬
Date
Tags
2 more properties

트랜잭션 (Transaction)

트랜잭션의 격리 수준을 알아보기 전에 먼저 트랜잭션이란 뭘까? 필자의 경우에 대학교에서 이해도 못하고 달달 외웠는데 면접에서 제대로 대답하지 못했던 기억이 있다.
당시 1차 화상 인터뷰
채용 담당자님: 트랜잭션을 간단하게 설명해 주실 수 있으실까요??
나: (우물쭈물거리며) 트랜잭션은 데이터베이스에서 처리하는 하나의 단위로 (주저리주저리) 성공 시에는 Commit되어 반영되고 실패 시에는 Rollback 되는 것으로 (주저리주저리)
거의 1분 동안 아는 지식을 끌어모아 대답했는데 채용 담당자님이 친절하게 설명해주셨다.
채용 담당자님: “트랜잭션에 대해 잘 알고 계신것 같아요. 이렇게 설명하시면 더 편해요.”
→ 트랜잭션은 태우님 집에서 학교까지 가는 것으로 빗댄다면 이렇게 설명할 수 있어요.
1.
집에서 나온다
2.
버스를 탄다
3.
지하철을 탄다
4.
학교까지 걷는다.
5.
학교에 도착한다.
그런데 만약에 버스에서 Exception이 발생하였다면 모든 작업은 실패하게 되고 다시 집에서부터 새로 시작하는거에요. (여기서 ACID와 그 중 하나인 원자성이 생각났음)
서론이 길었는데 트랜잭션은 데이터베이스에서 수행되는 작업의 논리적인 단위로 여러단계의 ACID를 보장하여 성공 혹은 실패로 완결되는 논리적인 작업의 단위이다.
채용 담당자님이 설명했던 대로 트랜잭션을 집에서 학교를 가는 과정으로 빗대어 간단하게 그려보자면 아래와 같다.
Take-The-Subway 단계에서 DoorNotFoundException이 발생하여 다시 롤백된 모습이다.
트랜잭션의 격리는 “격리”라는 말에서 나오듯 2개 이상의 트랜잭션이 함께 실행하며 문제를 일으킨다.
아래는 2개 이상의 트랜잭션이 동시에 실행되면서 일어나는 문제들을 5가지 단계로 구분한 “학교를 가는 과정”을 예시로 설명한다.

Dirty-Read

1.
나의 위치를 가져오는 트랜잭션 (T1)
2.
내가 학교를 가는 트랜잭션 (T2)
T2 트랜잭션에서 내가 학교를 가기 위해 1단계와 2단계를 거쳐서 3단계인 (Take-The-Subway) 단계로 왔다.
아직 T2 트랜잭션은 종료되지 않음
나의 위치 → 지하철 역
이 떄 T1 트랜잭션이 나의 위치를 가져오기 위해 SELECT 문을 실행한다.
결과: 나의 위치 → 지하철 역
동시에 T2 트랜잭션에서 DoorNotFoundException이 발생하며 나의 위치가 다시 집으로 Rollback되었다.
위 상황에서 데이터의 정합성이 깨진다.
T1 트랜잭션이 읽은 나의 위치: 지하철 역
T2 트랜잭션으로 롤백된 나의 위치: 집
이 상황을 그림으로 그려보았다. [T1] - [Taewoo’s Location] - [T2]

Non-Repeatable-Read

1.
나의 위치를 가져오는 트랜잭션 (T1)
2.
내가 학교를 가는 트랜잭션 (T2)
이번에도 두 트랜잭션 (T1, T2)으로 설명해보려 한다.
트랜잭션 T1 동작 과정
1.
나의 위치를 가져온다. [나의 위치: 집]
2.
[동시에 T2 트랜잭션이 실행되는 중]
3.
동일한 조건에서 나의 위치를 가져온다. [나의 위치: 지하철 역]
트랜잭션 T2 동작 과정
1.
나의 위치를 지하철 역으로 변경한다.
T1 트랜잭션 입장에서 같은 조건에서 실행된 SELECT 쿼리의 결과가 다름을 알 수 있다.
아래 사진에 빨간색으로 표시한 부분이 T1의 동작과정 1번과 3번이다.
란색 박스 부분에서 값이 변경됨을 알 수 있다.

Phantom-Read

1.
나의 위치를 가져오는 트랜잭션 (T1)
2.
내가 학교를 가는 트랜잭션 (T2)
T1 트랜잭션이 데이터를 읽어온다.
T1 트랜잭션은 아직 종료되지 않음.
읽어온 데이터 (A,B,C,D)
T2 트랜잭션이 데이터를 추가한다.
데이터 (E,F,G)를 추가함
T1 트랜잭션이 데이터를 다시 읽는다.
여기서 팬텀 리드가 발생한다.
읽어온 데이터 (A,B,C,D,E,F,G)
격리 레벨 설정으로 일어날 수 있는 대표적인 세 가지 문제를 알아보았다.
Dirty-Read
Non-Repeatable-Read
Phantom-Read
이제 이 세 가지 문제를 일으키는 격리 레벨과 이 세 가지 문제를 막을 수 있는 격리 레벨을 알아보자.

Read-Uncommitted

T1 트랜잭션이 수정하고 커밋되지 않은 데이터를 T2 트랜잭션이 읽을 수 있도록 하는 격리 레벨

Read-Committed

T1 트랜잭션이 수정하고 커밋되지 않은 데이터는 T2 트랜잭션이 읽을 수 없다. 그러나 T1 트랜잭션에서 커밋된 데이터는 여전히 T2에서 읽을 수 있도록 하는 격리 레벨

Repeatable-Read

T2 트랜잭션에서 한 번 읽어온 값은 T2 트랜잭션이 종료되는 시점까지 같은 값만 반환하는 격리 레벨

Serializable