Database

[DATABASE] Isolation Level

ju_young 2023. 12. 5. 15:09
728x90

Dirty Read

x = 10, y = 20 일 때 다음 작업을 수행한다고 해보자.

 

transaction 1 transaction 2
read(x) => 10  
  write(y=70)
read(y) => 70  
write(x=80)  
commit  
  rollback(y=20)

그러면 최종적으로 x = 80, y = 20이 되는데 이 때 x는 commit되지 않은 y를 read하여 얻은 결과이다. 이렇게 commit되지 않은 값을 읽는 것Dirty Read라고 부른다.

 

Rollback이 일어나지 않은 다른 경우에도 Dirty Read라고 부를 수 있는데 먼저 x = 50, y = 50 일 때 다음 작업을 수행한다고 해보자.

 

transaction 1 transaction 2
read(x) => 50  
write(x=10)  
  read(x) => 10
  read(y) => 50
  commit
read(y) => 50  
write(y=90)  
commit  

이 경우는 transaction 2에서의 x + y = 60이되고 transaction 1에서는 x + y = 100이 되어 데이터 불일치가 발생한다고 볼 수 있다. 따라서 이러한 경우도 Dirty Read라고 부르기도 한다.

Non-repeatable Read

x = 10일 때 다음 작업을 수행한다고 해보자.

 

transaction 1 transaction 2
read(x) => 10  
  read(x) => 10
  write(x=50)
  commit
read(x) => 50  

이 때 같은 데이터를 하나의 transaction 안에서 여러번 read 했을 때 값이 변경되는 현상이 일어난다. 그런데 Transaction의 Isolation 특성상 transaction끼리는 서로 영향을 주면 안되기 때문에 이상하다고 볼 수 있다. 그리고 이러한 현상을 Non-repeatable Read (Fuzzy Read)라고 부른다.

Phantom Read

v라는 값을 가지는 tuple이 있을 때 v=10인 tuple1과 v=50인 tuple2에 다음 작업을 수행한다고 해보자.

 

transaction 1 transaction 2
read(v=10) => tuple1  
  write(tuple2.v=10)
  commit
read(v=10) => tuple1, tuple2  
commit  

이때도 Non-repeatable Read와 비슷하게 다른 transaction에 의해 없던 데이터가 생기는 것Phantom Read 라고 부른다.

NOTE
Dirty Read, Non-repeatable Read, Phantom Read와 같은 이상한 현상들이 모두 발생하지 않게 만들 수 있지만 제약사항이 많아져 동시 처리가능한 트랜잭션 수가 줄어들기 때문에 DB의 전체 throughput이 감소하게된다.

Isolation Level

  • Isolation Level별 허용 여부
Isolation Level Dirty Read Non-reapeatable read Phantom read
Read uncommitted O O O
Read committed X O O
Repeatable read X X O
Serializable X X X

NOTE
Serializable LevelDirty Read, Non-repeatable Read, Phantom Read 뿐만 아니라 이상한 현상 자체가 발생하지 않는 Level이다.


Dirty Write

x=10에 대해 다음 작업을 수행한다고 해보자.

 

transaction 1 transaction 2
write(x=10)  
  write(x=100)
  commit
abort  

transaction 2에서 100으로 수정했지만 transaction 1이 rollback을 하면서 잘못된 결과를 가져다주게 된다. 이렇게 commit이 안된 데이터를 write하는 현상을 Dirty Write라고 부른다.

Lost Update

x=50에 대해 다음 작업을 수행한다고 해보자.

transaction 1 transaction 2
read(x) => 50  
  read(x) => 50
  write(x=200)
  commit
write(x=100)  
commit  

최종적으로 x=100을 가지게되고 transaction 2에서 작업한 결과가 Lost된다. 이렇게 Update 작업이 사라지는 현상을 Lost Update라고 부른다.

Read Skew

x=50, y=50일 때 다음 작업을 수행한다고 해보자.

 

transaction 1 transaction 2
 read(x) => 50
read(x) => 50  
write(x=10)  
read(y) => 50  
write(y=90)  
commit  
  read(y) => 90

transaction 1에서의 x + y = 100, transaction 2에서의 x + y = 140이되어 데이터 불일치가 발생하게된다. 이렇게 일관성 없는 데이터를 읽는 현상을 Read Skew라고 부른다.

NOTE
Read Scew는 Commit된 결과를 읽었을 때 발생하는 현상이고 Dirty Read는 Commit되지 않은 결과를 읽었을 때 발생하는 현상이다.

Write Skew

x=50, y=50이고 x + y >= 0이라는 제약사항이 있을 때 다음 작업을 수행한다고 해보자.

 

transaction 1 transaction 2
read(x) => 50  
read(y) => 50  
  read(x) => 50
  read(y) => 50
write(x=-30)  
  write(y=-40)
commit  
  commit

transaction 1 작업과 transaction 2 작업에서는 각각 x + y >= 0이라는 제약사항을 위반하지 않지만 두 transaction이 모두 수행된 결과는 제약사항을 위반하게 된다. 이러한 현상을 Write Skew라고 부른다.


Snapshot Isolation

x=50, y=50일 때 다음 작업을 수행한다고 해보자.

 

transaction 1 snapshot 1 transaction 2 snapshot 2
read(x) => 50 x=50    
write(x=10) x=10    
    read(y) => 50 y=50
    write(y=150) y=150
    commit  
read(y) => 50 x=10, y=50    
write(y=90) x=10, y=90    
abort      

snapshot은 transaction이 시작될 때의 기준의 데이터를 의미한다. 따라서 transaction1의 read(y)를 수행했을 때 transaction2에서 수행한 write(y=150)이 반영된 데이터가 아닌 그 이전 값을 가져오는 것이다.

 

또한 transaction1에서 write(y=90)이 적용된다면 Lost Update 현상이 일어나게 될 것이다. 하지만 Snapshot Isolation에서는 처음 commit한 결과를 반영하고 이후에 수행하는 작업은 rollback처리를 한다.

728x90