diff --git "a/CS Deep Dive/Database/\355\212\270\353\236\234\354\236\255\354\205\230 \352\262\251\353\246\254 \354\210\230\354\244\200(Transaction Isolation Level).md" "b/CS Deep Dive/Database/\355\212\270\353\236\234\354\236\255\354\205\230 \352\262\251\353\246\254 \354\210\230\354\244\200(Transaction Isolation Level).md" index 56b9cfd0..d6cb4fda 100644 --- "a/CS Deep Dive/Database/\355\212\270\353\236\234\354\236\255\354\205\230 \352\262\251\353\246\254 \354\210\230\354\244\200(Transaction Isolation Level).md" +++ "b/CS Deep Dive/Database/\355\212\270\353\236\234\354\236\255\354\205\230 \352\262\251\353\246\254 \354\210\230\354\244\200(Transaction Isolation Level).md" @@ -1,5 +1,20 @@ -# 트랜잭션 격리 수준(Transaction Isolation Level) + +## 트랜잭션 격리수준이 필요한 이유 + + + +image + +Race Condition이 발생하므로 트랜잭션을 서로 격리해서 다른 트랜잭션이 영향을 주지 못하게 해야 한다. +


+image + + +가장 쉬운 방법은 트랜잭션을 순서대로 실행하는 방법이다. +동시 접근 문제가 아예 없어지지만, 한 개의 트랜잭션만 처리하기 때문에 성능 저하가 일어난다. +따라서 상황에 따라서 격리수준을 선택해야 한다. +


**트랜잭션 격리수준(isolation level)** 이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다. - 간단하게 말해 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것이다. @@ -11,20 +26,88 @@ ## 격리 수준에 따라 발생할 수 있는 문제 **1. Dirty Read** +- Dirty read를 막지 않은 경우 + +image + +위와 같은 상황이 발생하면 읽지 않은 메세지는 존재하지만 읽지 않은 메세지의 수는 0이 되는 모순적인 상황이 발생한다. +

+- Dirty read를 막은 경우 +image +
+ +**2. Dirty Write** + +- Dirty Write를 막지 않은 경우 +image +

+ +- Dirty Write를 막은 경우 +image +

+ +Dirty Read/Write를 막지 않은 경우 - 트랜잭션 A의 커밋하기 이전 변경사항을 트랜잭션 B가 참조한다. - 트랜잭션 A가 문제가 생겨 ROLLBACK을 해도 B는 계속 로직을 수행한다. - 데이터 부정합이 발생한다. -**2. Non-Repeatable Read** +


+ +**3. Read Skew1** - 트랜잭션 A가 같은 쿼리를 반복해서 수행하는 도중, 트랜잭션 B가 A의 실행에 사용하는 값을 변경한다. - 트랜잭션 A가 같은 쿼리를 수행하는데에도 B에 의해 다른 결과가 나온다. - 같은 쿼리문에 대해 일관된 결과값이 나와야하는 `REPEATABLE READ` 정합성을 만족하지 못한다. +- Dirty Read/Write를 막은것 만으로는 해결할 수 없다. +

+read skew 문제의 예시 +image +

+ +스냅숏 격리를 이용하여 해결한 경우 + +image + +

+

+ +**4. Lost Update** + +- 같은 데이터를 쓸 때 발생한다. + +image + +

+ +명시적 잠금으로 해결한 경우 + +image + +

+ +CAS를 이용한 경우 + +image + +


+ +**5. Read Skew2** + +- 같은 데이터를 쓰지 않지만 실제로는 경쟁 상태에 있다. + + image + +ex) count쿼리의 값이 2이면 A,B 둘 중 하나를 수정하는 경우이다. + +

+ +인덱스 잠금을 이용해서 해결 + +image -**3. Phantom Read** +


-- 한 트랜잭션 내에서 같은 쿼리를 두 번 실행했는데, 첫 번째 쿼리에서 없던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상이다.