오래 못 할 짓 하지 않기

[ 데이터베이스 ] 16. Isolation Level 본문

3학년 1학기/데이터베이스(DB)

[ 데이터베이스 ] 16. Isolation Level

쫑알bot 2024. 1. 14. 23:39
728x90

Transaction들이 동시에 실행될 때 발생할 수 있는 이상 현상들

Dirty read

 

이런 상황에서 Transaction 2번을 abort = rollback을 한다면?

y = 20 이 된다.

 

하지만 Transaction 1번을 이미 commit 했기에 x=80으로 유지된다.

 

이와 같이 (Rollback이 되어서) Commit 되지 않은 변화를 읽어서 생기는 현상을

Dirty read 라고 한다.

 

 


Non-repeatable read

 

하나의 Transaction 에서 읽은 x의 값이 다르다.

이는 Isolation 관점에서 올바르지 않은 현상이다.

 

Isolation은 여러 transaction이 동시에 실행되어도 같은 결과를 가져야하기 때문이다.

즉, Transaction 서로 영향을 받지 않고 독립적이어야 하는데 이렇게 되면  Isolation이 아니게 된다.

 

이렇게 같은 데이터의 값에 2번 접근하는데 값이 다르게 나오는 것

Non-repeatable read 현상이라고 한다.

 

 


 

Phantom read

 

한 Transaction에서 같은 조건(=연관있는 조건)으로 2번 실행했을 때, 다른 값(=없던 데이터)이 나오는 경우

Phantom read라고 한다. 

 


이 모든 현상이 일어나지 않도록 만들기에는 제약사항이 많아지고

동시에 처리 가능한 트랜잭션 수가 줄어, DB 전체 처리량이 줄어든다.

 

따라서, Isolation 레벨에 따라 이러한 현상을 허용하여 상황에 맞게 사용하자!

 

 

- Read committed : commit된 것들만 읽는다. 

- Serializable : 여기에 적혀있는 이상한 현상이외에도 그런 현상이 절대 발생하지 않는다.

 


 

Dirty write

x = 0 에서 시작

1. Tx1 에서 Write → x = 10

2. Tx2 에서 Write → x = 100

3. Tx1 에서 abort = x = 10 으로 실행하기 전 상태로 돌아감

   → x = 0 

이런 경우에는 Tx2에서 실행한 x = 100이 사라진다.

 

그러면, Tx2에서 Rollback을 한다면?

x = 100이 되기 전인 x = 10으로 바뀔 것이고 이것도 올바른 isolation의 형태가 아니다.

 

만약에 Tx2에서 commit을 하고 Tx1에서 abort를 하더라도

Tx2에서 실행한 값은 사라지게 된다. Tx1 의 값이 commit되지 않았는데 Tx2에서 썼기 때문에

 

따라서 이렇게 Commit되지 않은 데이터를 write하는 경우에 생기는 현상

Dirty write라고 한다.

  

※ Rollback 시에 정상적인 recovery는 매우 중요하다                            ※

※   따라서, 모든 Isolation Level에서 Dirty write는 허용하면 안된다.  ※

 


Lost Update

 

 

위 Transaction을 실행한 후에는 Tx1에서 실행한 값만 나오게 되고

Tx2에서 업데이트 된 내역이 사라진다.

 

이와같이 Transaction끼리 Update 내역을 덮어 쓰는 경우

Lost Update라고 한다.

 

(계좌 잔액이라고 생각하면 어떤 게 잘못된지 바로 알 수 있다)

 

 


Dirty read 확장판

위와 같이 Tx1에서 Write(x=10) 이후에 commit을 하지 않았는데도

Tx2에서 read(x)를 하기에 Dirty read인 것이다.

 

굳이 abort 가 발생하지 않아도 Dirty read가 되는 경우도 있다.

 

Read data를 했을 때 Data consistency에 의해

Tx1이든 Tx2든 합해서 100이 나와야 한다. 하지만 Tx2에서는 60가 나온다.

 


Read skew

 

DB에 결과적으로 x=10 , y=90으로 총 합 100이 있다.

하지만 Tx2에서 읽은 값으로는 합이 140이다.

 

이와 같이 Inconsistent한 데이터를 읽는 경우Read Skew라고 한다.

 

● Non-repeatable read 와 차이점 

 - Non- "'         :  read (x) ... read(x)

 - Read Skew :  read(x) ... read(a)

 


Write Skew

 

이전 예제들에서 제약사항 하나가 생긴다.

[ X + Y >= 0 ]

 

Tx1, Tx2 모두 실행하기 위해서는 

X와 Y의 값을 읽고 인출을 해야한다.

 

1.  TX1에서 X,Y값을 읽는다.  → x=50, y=50 (조건 O)

2.  TX2에서 X,Y값을 읽는다.  → x=50, y=50 (조건 O)

3.  TX1에서 X값을 -80 한 후에 Commit    → x=-30, y=50 (조건 O)

4.  TX2에서 Y값을 -40 한 후에 Commit    → x=50, y=-40 (조건 O)

 

하지만 DB에 남아있는 값은 -30 과 -40 으로 -70 이고, 조건에 맞지 않다.

 

이와 같이 Inconsistent한 데이터를 쓰는 경우 Read Skew라고 한다.

 


Phantom read 확장판

 

read(v>10)과 read(cnt)가 동시에 일어났으면 read(cnt)값이 저게 아니었을 것이다.

 

read(v>10)에서는 만족하는 게 없었는데

그 밑에 read(cnt)에서는 만족하는 게 1개 있다고 뜸

 

 

굳이 같은 조건이 아니라 관련있는 조건으로 했을 때 다르게 나오는 것Phantom read이다.

 

 

 


SNAPSHOT ISOLATION

 

Isolation Level을 구분한 것에는 상업적인 DBMS에서 사용되는 방법이 반영되지 않았다.

이에 따라 나온 것이 SNAPSHOT ISOLATION 인데, 이는 기존 Isolation Level과 조금 다르다.

 

● 기존 : 이상한 현상들을 어느 정도 허용하느냐에 따른 Level 정의

● SNAPSHOT ISOLATION : Isolation의 구현 방식에 따라 정의

 

[ 특징 ]

● Transaction 시작 전 Commit된 데이터만 보인다. ( commit하지 않으면 DB에서는 아무 변화 없는 걸로 보임 )

● First-commiter win : Write 로 데이터가 충돌하면 먼저 Commit한 놈이 이긴다 ( 할리갈리 느낌임 , 내가 먼저 썼다! )

 

Transaction 을 시작할 때 Snapshot 사진을 찍듯이 그 상태를 저장한다.

그리고 변경사항이 있으면 DB가 아닌 Snapshot에 업데이트를 한다.

▶ Snap Shot of Transaction1 : x=50  → x=10

▶ Snap Shot of Transaction2 : y=50  → y=150

후에 commit하면 DB에도 적용된다.

 

 

그리고 Transaction 1의 마무리 부분을 실행한다.

Read(y)를 하면 그 명령어가 있는 Transaction의 Snapshot의 값을 받는다.

 

▶ Snap Shot of Transaction1 : x=50 , y=50  → x=10 , y=90

 

 

그런 다음, Transaction의 마무리 부분도 commit을 하려고 하는데 

Tx1 , Tx2에서 같은 Data에 대해 Write를 하고있는데,

Tx1에서 계산한 y를 업데이트 한다면 Tx2에 대한 lost update상황이 발생한다.

 

이런 상황에서 Snapshot isolation은 먼저 Commit한 Transaction만 인정을 하고

뒤에 Commit한 Transaction은 abort한다. 

 

 

다양한 현상들을 알고있으면

이런 현상이 발생했을 때, 무엇이 문제인지 더욱 잘 파악할 수 있다.

 

 

(출처)

유튜브 쉬운코드