Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 플라이웨이트
- SQL 삽입 공격
- @ControllerAdvice
- Proxy Patter
- java
- Connection Pool
- Effetive Java
- 이펙티브 자바
- Service Locator
- 트랜잭션
- @SpyBean
- Item04
- springboot
- NotBlank
- JPA
- db
- Spring Boot
- FCM
- Service Locator 패턴
- restTemplate
- 디자인 패턴
- Web
- 데이터베이스
- @MockBean
- multi module
- Effective Java
- Firebase
- @Valid
- deleteById
- NotEmpty
Archives
- Today
- Total
NoTimeForDawdling
트랜잭션 격리 수준(Isolation Level) 본문
트랜잭션 격리 수준이란?
- 트랜잭션 격리 수준이란 동시에 여러 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 말지 결하는 것입니다.
- 즉, 특정 트랜잭션이 다른 트랜잭션에 select, insert, update, delete를 허용할지 말지 결정하는 것입니다.
트랜잭션 격리 수준은 크게 4가지로 나뉩니다.
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
4개의 격리 수준에서 순서대로 뒤로 갈수록 각 트랜잭션 간의 데이터 격리(고립) 정도가 높아지며, 동시성은 떨어집니다.(성능 저하)
일반적인 온라인 서비스에서는 READ COMMITTED와 REPEATABLE READ 둘 중 하나를 많이 사용합니다.
READ UNCOMMITTED은 데이터 정합성의 문제가 많아 잘 사용하지 않습니다.
SERIALIZABLE은 동시성이 중요한 데이터베이스에서 거의 사용하지 않습니다.
각각의 격리 수준에 따라 발생할 수 있는 3가지 부정합 문제
1. Dirty Read
- Dirty Read는 트랜잭션 T1에서 A=1001로 update 하고 아직 commit하지 않았는데 다른 트랜잭션 T2가 commit하지 않은 A의 값을 읽을 수 있도록 허용하는 경우 발생합니다.
- 즉, 트랜잭션 T1이 특정 데이터를 update를 수행한 후 commit을 하지 않았는데 다른 트랜잭션(T2)이 commit하지 않은 값을 조회할 수 있는 경우를 뜻합니다.
- Dirty Read는 데이터가 나타났다가 사라졌다 하는 현상을 초래하므로 개발자와 사용자에게 굉장히 혼란스러울 수 있습니다.
2. Non Repeatable Read
- Non Repeatable Read는 트랜잭션 T1이 같은 쿼리를 두 번 실행했는데 그 결과값이 다른 경우를 말합니다.
- 즉, 트랜잭션 T1이 select을 두 번 하는 사이에 다른 트랜잭션(T2)이 update나 delete를 한 경우를 뜻합니다.
3. Phantom Read
- 트랜잭션 T1이 같은 쿼리를 두 번 수행 시 첫 번째 실행 시에 없던 레코드가 두 번째 실행시에 튀어나오는 경우를 말합니다.
위의 3가지 문제점을 각각의 트랜잭션 격리 수준과 함께 알아보겠습니다.
4가지 격리 수준
1. READ UNCOMMITTED
- READ UNCOMMITTED 격리 수준은 각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에 보입니다.
- 즉, 트랜잭션 T1이 아직 commit하지 않은 데이터를 다른 트랜잭션 T2가 조회하는 것을 허용합니다.
- 이렇게 특정 트랜잭션이 처리한 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있게 되는 Dirty Read 현상이 발생합니다.
- Dirty Read를 유발하는 READ UNCOMMITTED는 트랜잭션의 격리 수준으로 인정하지 않을 정도로 정합성에 문제가 많습니다.
2. READ COMMITTED
- READ COMMITTED 격리 수준은 트랜잭션 T1이 commit 한 데이터만 다른 트랜잭션 T2가 조회하는 것을 허용합니다.
- 즉, 특정 트랜잭션에서 변경한 데이터를 commit이 완료된 후에 다른 트랜잭션에서 조회할 수 있기 때문에 Dirty Read와 같은 현상은 발생하지 않습니다.
- 특정 트랜잭션(T1)이 update 하기 전 값은 Undo 영역으로 백업됩니다. 다른 트랜잭션이 같은 값을 조회할 때 Undo 영역에 있는 값을 조회하기 때문에 변경한 내용이 commit 되지 전까지는 변경 내역을 조회할 수 없게 됩니다.
- READ COMMITTED 격리 수준에서는 Non Repeatable Read 현상이 발생합니다.
- 예를 들어, 트랜잭션 T1에서 first_name이 'Toto'인 데이터를 검색했는데 일치하는 결과가 없습니다. 하지만 다른 트랜잭션 T2가 A라는 사원 이름을 'Toto'로 변경하고 commit을 실행한 이후, 트랜잭션 T1이 똑같은 SELECT 쿼리로 다시 조회하면 1건의 데이터가 나타납니다.
- 이렇게 하나의 트랜잭션 내에서 똑같은 SELECT 쿼리를 실행했을 때 항상 같은 결과를 가져오지 못하게 되는 Non Repeatable Read 현상이 발생합니다.
- READ COMMITTED 격리 수준은 오라클과 같은 DBMS에서 주로 사용됩니다.
3. REPEATABLE READ
- REPEATABLE READ는 선행 트랜잭션 T1이 읽은 데이터는 T1이 종료될 때까지 다른 트랜잭션이 udpate&delete를 허용하지 않습니다. 단 insert은 허용합니다.
- REPEATABLE READ는 Undo 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있도록 보장합니다.
- 예를 들어, 10번 트랜잭션 안에서 실행되는 모든 SELECT 쿼리는 트랜잭션 번호가 10(자신의 트랜잭션 번호) 보다 작은 트랜잭션 번호에서 변경한 것만 보게 됩니다. 그렇기 때문에 Non Repeatable Read 현상은 발생하지 않습니다.
- Undo 영역에 백업된 모든 레코드는 변경을 발생시킨 트랜잭션 번호가 포함돼 있습니다. REPEATABLE READ 격리 수준에서는 실행 중인 트랜잭션 가운데 가장 오래된 트랜잭션 번호보다 트랜잭션 번호가 앞선 Undo 영역의 데이터는 삭제할 수 없습니다.
- REPEATABLE READ 격리 수준에서는 Phantom Read 현상이 발생합니다.
- REPEATABLE READ 격리 수준은 MySQL에서 주로 사용합니다.
4. SERIALIZABLE
- SEREALIZABLE은 선행 트랜잭션 T1이 읽은 데이터는 T1이 종료될 때까지 다른 트랜잭션이 update&delete&insert 전부 불가능합니다.
- 격리 수준이 엄격한 만큼 동시 처리 성능도 다른 트랜잭션 격리 수준보다 훨씬 떨어집니다.
'DB' 카테고리의 다른 글
DB 데이터 캐싱(Caching) (0) | 2021.03.11 |
---|---|
ORM(Object Relation Mapping)이란? (0) | 2021.03.10 |
DB 인덱스(Index) (0) | 2021.03.04 |
Primary Key vs Unique Key (0) | 2021.02.26 |
트랜잭션(Transaction) (0) | 2021.02.16 |