Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database의 Isolation level에 대해서 정리한 내용입니다. #14

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 64 additions & 0 deletions Database/고립레벨.md
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
| <img src="https://user-images.githubusercontent.com/39688690/119251628-81d2a200-bbe2-11eb-85ad-868a3f28a4c4.png" width="100%"> | <img src="https://user-images.githubusercontent.com/39688690/119251673-b9d9e500-bbe2-11eb-83ff-655027ef6d14.png" width="100%"> | <img src="https://user-images.githubusercontent.com/39688690/119251692-d249ff80-bbe2-11eb-908f-1057cb44b71d.png" width="100%"> | <img src="https://user-images.githubusercontent.com/39688690/119251747-1a692200-bbe3-11eb-909f-962fc6d2f317.png" width="100%"> | <img src="https://user-images.githubusercontent.com/39688690/119251760-2f45b580-bbe3-11eb-8d5d-aa806f5c4438.png" width="100%"> | <img src="https://user-images.githubusercontent.com/39688690/119251766-366cc380-bbe3-11eb-914a-a5416e414c0a.png" width="100%"> |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| [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) |
| <img src="https://user-images.githubusercontent.com/39688690/119251750-2359f380-bbe3-11eb-9e04-996884842a3c.png" width="100%"> | <img src="https://user-images.githubusercontent.com/39688690/119252204-e2171300-bbe5-11eb-96bc-f0bb8b7a689b.png" width="100%"> | <img src="https://user-images.githubusercontent.com/37958836/119261127-e86eb480-bc10-11eb-83c9-7b774a449bf0.jpeg"> |
| [kommadot](https://github.com/kommadot) | [jsh-me](https://github.com/jsh-me) | [devsungmin](https://github.com/devsungmin) |
| <img src="https://user-images.githubusercontent.com/39688690/119251750-2359f380-bbe3-11eb-9e04-996884842a3c.png" width="100%"> | <img src="https://user-images.githubusercontent.com/39688690/119252204-e2171300-bbe5-11eb-96bc-f0bb8b7a689b.png" width="100%"> | <img src="https://user-images.githubusercontent.com/37958836/119261127-e86eb480-bc10-11eb-83c9-7b774a449bf0.jpeg"> | <img src="https://user-images.githubusercontent.com/42880886/173858732-0f17ac13-4a51-4269-90d2-053ebce57b06.png"> |
| [kommadot](https://github.com/kommadot) | [jsh-me](https://github.com/jsh-me) | [devsungmin](https://github.com/devsungmin) | [cyw320712](https://github.com/cyw320712) |


<br><br>
Expand Down Expand Up @@ -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)

<br>

Expand Down