diff --git "a/Database/\352\263\240\353\246\275\353\240\210\353\262\250.md" "b/Database/\352\263\240\353\246\275\353\240\210\353\262\250.md" new file mode 100644 index 0000000..e6fb07b --- /dev/null +++ "b/Database/\352\263\240\353\246\275\353\240\210\353\262\250.md" @@ -0,0 +1,64 @@ +## Isolation Level (고립 수준) + + - 고립레벨에 대한 학습 전에 [Transaction](https://github.com/cyw320712/Ready-For-Tech-Interview/blob/master/Database/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98.md)을 먼저 확인하자. + - 데이터베이스의 목적중에 가장 큰 것은 데이터의 공유이다. 즉, 여러 트랜잭션이 데이터에 접근할 수 있다는 의미이며, 동시성을 고려해야 한다는 의미이다. + - 트랜잭션의 ACID 원칙을 보장하기 위해서 데이터베이스는 트랜잭션의 Isolation level을 지정한다. + +### Isolation level의 의미 + - Isolation level은 DBMS에서 **트랜잭션들끼리 일관된 데이터를 얼마나 허용할 것인지**를 결정하는 기준이다. + - 간단히 말하자면, **트랜잭션 수행 중 다른 트랜잭션이 해당 데이터 조회를 허용할지 안할지의 정도를 정해둔 기준.** + - 고립 수준이 높아질수록 일관성은 높아지지만 동시성은 낮아진다. + - 고립 수준이 낮을수록 아래와 같은 읽기 이상 현상들이 발생할 수 있다. + +## 데이터베이스의 읽기 이상 현상 (Read Phenomena) + +### 1. Dirty Read + - 어떤 트랜잭션에서 실행이 끝나지 않은 트랜잭션에 대한 Uncommitted 결과를 확인해버리는 현상을 말한다. + - Transaction 1(T1)은 A=1를 읽으려 했지만, Transaction 2(T2)가 A를 5로 업데이트 해 commit 안했지만, T1이 A를 5로 잘못 읽는 상황 + - 공유 Lock을 걸어 T1이 A를 접근하는 동안 다른 트랜잭션이 접근하지 못하게 함으로써 해결한다. + +### 2. Non Repeatable Read + - 동일한 쿼리를 2번 실행할 때 다른 트랜잭션이 수정/삭제하는 경우 + - T1이 같은 쿼리를 2번 실행했는데, 그 사이에 T2이 해당 데이터에 대해 Update/Delete함으로써 두 쿼리 사이의 결과값이 다른 경우 + - 트랜잭션 완료시까지 수정이나 삭제를 제한함으로써 해결한다. + +### 3. Phantom Read + - 동일한 쿼리를 2번 실행할 때 다른 트랜잭션이 업데이트하는 경우 + - T1이 같은 쿼리를 두 번 실행했는데, 첫 번째 실행시 없던 record가 두 번째 실행 때 생기는 경우 + - T1이 읽은 데이터는 다른 트랜젝션에서 갱신, 삭제뿐만아니라 삽입조차 제한함으로써 해결한다. + +## Isolation Level의 종류 +- 고립 수준에는 다음 4가지 수준이 존재한다. + +![image](https://user-images.githubusercontent.com/42880886/173832835-c6148d47-7bb8-43cb-8d15-9aebe62be148.png) + + +### 1. **Level 0. Read Uncommitted** + - **Uncommitted된 결과를 read할 수 있다.** + - 예를 들어 transaction 1 작업중에 transcation 2가 값을 변경할 수 있는데, transaction 1은 변경되기 전의 값을 읽기 때문에 최대한 사용하지 않아야 함. (Dirty read) + - 해당 격리 수준에서는 데이터베이스 결과의 일관성을 유지하기 힘들다. 하지만, 동시성은 향상된다. + - Dirty Read, Non Repeatable Read, Phantom Read 등의 문제가 발생할 수 있다. + +### 2. **Level 1. Read Committed** + - Read Committed는 **트랜잭션이 작업하는 시점에 Lock**을 건다 + - 이 Lock을 거는 주체는 INSERT나 UPDATE와 같은 처리 세션인데, 이렇게하면 세션은 INSERT나 UPDATE가 되기까지 기다리기 때문에 Dirty Read를 피할 수 있다. + + > Mysql 제외 대부분의 DBMS에서 사용하는 기본 Isolation level이다. + + - INSERT나 UPDATE와 같은 처리 세션세어 Lock을 걸고, SELECT같이 쿼리하는 세션은 대기한다. + - Non Repeatable Read와 Phantom Read의 문제가 발생할 수 있다. + +### 3. **Level 2. Repeatable Read** + - Repeatable Read는 **Read Committed와 마찬가지로 트랜잭션이 작업하는 시점에 Lock**을 걸지만, 여기서는 **SELECT와 같이 쿼리하는 세션이 Lock을 건다.** + - MySQL에서 Default Isolation Level이다. + - 쿼리하는 세션이 Lock을 걸고, 처리하는 세션은 대기한다. + - Phantom Read의 문제는 여전히 발생 + +### 4. **Level 3. Serializable** + - Serializable은 직렬화함으로써 **모든 동작이 순서를 가지고 동작한다. (동시성 x)** + - 최상위 Isolation level이며 데이터의 안정성이 매우 중요한 특수한 상황이 아닌 이상 거의 사용하지 않는다. + - 발생할 수 없는 문제는 없다. + +## 참조할만한 글 + +https://medium.com/@huynhquangthao/mysql-testing-isolation-levels-650a0d0fae75 diff --git a/README.md b/README.md index c911f2c..c49f3bd 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ | | | | | | | | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | | [huhsay](https://github.com/huhsay) | [hzoou](https://github.com/hzoou) | [woung717](https://github.com/woung717) | [Bellroute](https://github.com/Bellroute) | [ksshlee](https://github.com/ksshlee) | [goodGid](https://github.com/goodGid) | -| | | | -| [kommadot](https://github.com/kommadot) | [jsh-me](https://github.com/jsh-me) | [devsungmin](https://github.com/devsungmin) | +| | | | | +| [kommadot](https://github.com/kommadot) | [jsh-me](https://github.com/jsh-me) | [devsungmin](https://github.com/devsungmin) | [cyw320712](https://github.com/cyw320712) |

@@ -143,7 +143,7 @@ - [이상(Anomaly)](https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Database/%EC%9D%B4%EC%83%81(Anomaly).md) - [인덱스(INDEX)](https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Database/%EC%9D%B8%EB%8D%B1%EC%8A%A4(INDEX).md) - [트랜잭션](https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Database/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98.md) -- [트랜잭션 격리수준]() +- [트랜잭션 격리수준](https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Database/고립레벨.md)