2022. 8. 5. 23:24ㆍDataBase/DB 이론
✅ 트랜잭션 격리 수준에 대해서 알아보자
트랜잭션 격리수준(Isolation level)
트랜잭션 격리수준이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다. 쉽게 말하자면 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것이다.
트랜잭션 격리 수준은 크게 4가지로 구성되어 있다.
- READ UNCOMMITED(커밋되지 않은 읽기)
- READ COMMITTED(커밋된 읽기)
- REPEATABLE READ(반복 가능한 읽기)
- SERIALIZABLE(직렬화 가능)
READ UNCOMMITED ->SERIALIZBLE 순으로 갈수록 고립(격리) 정도가 높아지며, 성능이 떨어집니다. 격리 수준이 낮을수록 동시성은 증가하지만 격리 수준에 따른 다양한 문제가 발생하게 된다. 즉 격리 수준이 낮을수록 더 많은 문제가 발생하게 된다! (아래 표는 격리 수준에 따른 문제점을 정리한 표이다.)
격리 수준 | DIRTY READ | NON_REPEATABLE READ | PHANTOM READ |
READ UNCOMMITTED | O | O | O |
READ COMMITTED | O | O | |
REPEATABLE READ | O | ||
SERIALIZABLE |
각각의 격리수준에 대해서 조금 더 상세하게 알아보자.
READ UNCOMMITTED
- 커밋하지 않은 데이터를 다른 트랜잭션이 볼 수 있다. 이 격리 수준에서는 다음과 같은 문제가 발생할 수 있음
- 트랜잭션 A가 데이터를 수정 중인 상태이고 커밋하지 않았다.
- 트랜잭션 B에서 수정 중인 데이터를 조회할 수 있다.(이러한 행위를 DIRTY READ라고 한다.)
- 트랜잭션 A가 RollBack을 한다
- 트랜잭션 B는 커밋되지 않는 데이터를 사용하려 로직을 수행한다
데이터 정합성에 심각한 문제가 발생할 수 있다.
이러한 DIRTY READ를 허용하는 격리 수준을"READ UNCOMMITTED"라 한다.
Read Uncommit은 어떠한 락(X-Lock, S-Lock)등을 사용하지 않으므로 Dirty Read 현상이 발생하게 되는것이다!
READ COMMITTED
- 특정 트랜잭션이 COMMIT이 되어야만 다른 트랜잭션에서 조회가 가능하다. 따라서 "DIRTY READ"가 발생하지 않는다.
오라클 DBMS에서 기본적으로 사용하고 있고, 온라인 서비스에서 가장 많이 선택되는 격리 수준이다.
언뜻 보면 정합성 문제가 해결된 것 같지만, 여기서는 "NON-REPEATABLE READ" 부정합 문제가 발생할 수 있다.
- A 트랜잭션가 주문 금액을 조회함(10만원 조회됨)
- B 트랜잭션에서 주문 금액을 12으로 변경 후 Commit
- A 트랜잭션에서 주문 금액을 다시 조회함(12만원 조회됨)
위와 같이 하나의 트랜잭션 내에서 동일한 SELECT을 수행했을 경우 항상 같은 결과를 반환해야 하는 REPEATABLE READ 정합성에 어긋나게 된다. 즉, DIRTY READ는 허용하지 않지만, "NON-REPEATABLE READ"는 허용하는 격리 수준을 "READCOMMITED"라 한다
REPEATABLE READ
- 해당 격리수준은 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리 수준이다.
Mysql에서 기본적으로 사용하고 있고, 이 격리 수준에서는 "NON-REPEATALBE READ" 부정합이 발생하지 않는다.
하지만 PHANTOM READ가 발생할 수 있다. 예를 들면
- A 트랜잭션에서 10살 이하의 회원을 조회함(한 명이 나옴)
- B 트랜잭션에서 5살 회원을 추가하고 커밋함
- A 트랜잭션에서 다시 10살 이하의 회원을 조회했을 때 한명이 더 추가된 조회 결과가 나오게 됨
이처럼 반복 조회 시 결과 집합이 달라지는 것을 "PHANTOM READ"라고 한다.
PHANTOM READ는 REPEATABLE 격리 수준 이하에서만 발생하고, INSERT에 대해서만 발생한다.
SERIALIZABLE
- 가장 엄격한 격리 수준이다. Select 작업에도 공유 Lock을 설정하게 되고, 동시에 다른 트랜잭션에서 이 레코드를 변경하지 못하게 되어 동시성 처리 성능이 다른 격리 수준보다 떨어지고, 성능 저하가 발생하게 된다.
대부분 어플리케이션은 동시성 처리가 중요하므로 DB들은 보통 READ COMMITTED 격리 수준을 기본으로 사용한다.
참고자료
- 자바 ORM 표준 JPA 프로그래밍(저자:김영한)
- https://velog.io/@sa1341/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC-%EC%88%98%EC%A4%80Isolation-Level%EC%9D%B4%EB%9E%80
- https://kuaaan.tistory.com/97?category=91639
'DataBase > DB 이론' 카테고리의 다른 글
Connection/Read Timeout (0) | 2022.08.22 |
---|---|
트랜잭션 1편 (0) | 2022.07.26 |
Connection Pool (0) | 2022.07.24 |