본문 바로가기
코딩 공부 기록/SQL

[MSSQL] 격리 수준 (ISOLATION)

by Murphy0v0 2024. 12. 9.

격리 수준(ISOLATION)이란?

트랜잭션이 수행될 때 다른 트랜잭션으로부터 영향을 받지 않게 고립성을 유지시키는 것.

다른 트랜잭션에 영향을 받지 않도록 잠금(Lock)을 사용하여 격리 수준으로 잠금의 유형을 정리한다.

 


 

격리 수준의 필요성

  • 데이터 일관성 유지 : 트랜잭션 간의 간섭을 방지하여 데이터의 일관성을 보장
  • 동시성 제어 : 여러 트랜잭션이 동시에 실행될 수 있도록 하여 성능과 데이터 무결성 간의 균형을 맞춤
  • 비즈니스 요구 사항 충족 : 각 애플리케이션의 데이터 처리 요구에 맞는 격리 수준을 선택할 수 있음
  • 트랜잭션 충돌 방지 : 동시에 실행되는 트랜잭션 간의 충돌을 방지하여 데이터 무결성을 유지
  • 성능 최적화 : 적절한 격리 수준을 통해 성능과 데이터 일관성 간의 균형을 조절

 

동시성에 대한 3가지 문제점

1. Dirty Read : 트랜젝션에서 데이터를 읽을 때 아직 COMMIT 되지 않은 데이터를 읽는 현상

https://youtu.be/5slfUXBnU78?si=BmMVjie00U4WsWjl 참고

Session 52와 Session 53이 있다.

처음에 Session 53에서 조회를 하고 NO는 1, GRADE는 A이다.

 

Session 53에서 GRADE를 B로 UPDATE 한다.

 

Session 52에서 격리 수준을 READ UNCOMMITTED로 설정한 후 조회를 하면 GRADE가 B로 조회된다.

 

그 사이에 Session 53에서 ROLLBACK을 하면 다시 GRADE는 A로 바뀌게 된다.

 

Session 52에서 다시 조회를 하면 GRADE가 A로 조회된다.

 

이 경우, Session 52에서는 조회만 했는데 결과가 다르게 나오기 때문에, 그 데이터를 가지고 연산을 하거나 처리를 한다면 잘못된 결과가 나올 수 있다.

 

 

 

 

2. Non-Repeatable Read : 트랜젝션에서 읽은 데이터가 해당 트랜잭션이 종료되기 전에 다른 트랜잭션에서 변경, 삭제되어 다시 읽었을 때 읽었던 데이터의 결과 갑이 다른 현상

https://youtu.be/5slfUXBnU78?si=BmMVjie00U4WsWjl 참고

Session 52에서 READ COMMITTED 격리 수준으로 조회를 했을 때, NO는 1, GRADE는 A이다.

 

그리고 Session 53에서 GRADE를 B로 바꾸고,

그 직후 Session 52에서 같은 쿼리로 조회하면 GRADE가 B가 된다.

 

Session 52 입장에서는 같은 쿼리에 다른 결과값이 나오게 된다.

 

 

 

3. Phantom Read : 트랜잭션에서 읽은 데이터가 해당 트랜잭션이 종료되기 전에 다른 트랜잭션에서 데이터를 삽입하여 다시 읽었을 때 결과 집합이 다른 현상

https://youtu.be/5slfUXBnU78?si=BmMVjie00U4WsWjl 참고

 

1번, 2번과 유사하다.

 

Session 52에서 select를 하고, Session 53에서 데이터를 INSERT 한다.

 

그 후 Session 52에서 다시 SELECT를 하면 전에 없었던 값이 생겨났기에 Ghost 레코드가 발생한다.

 


 

격리 수준 종류

 

1. READ UNCOMMITTED

 

- 데이터가 수정되었지만 아직 COMMIT 되지 않은 데이터를 읽을 수 있도록 지정하는 격리 수준으로

데이터 조회 시 Key에 공유 잠금(S)을 요청하지 않는다.

(공유 잠금을 요청하지 않음으로써, 트랜잭션이 다른 트랜잭션의 데이터를 읽는데 걸리는 시간을 최소화하고, 여러 트랜잭션이 동시에 실행될 수 있도록 한다.)

- 고립성이 낮고 동시성이 높은 격리 수준.

 

Session 53에서 UPDATE 한 구문이 COMMIT되지 않았지만 Session52에서 READ UNCOMMITTED로 조회하면 UPDATE된 데이터까지 조회된다. ( Dirty Read가 발생한다. )

이후 Session 53에서는 ROLLBACK되어 UPDATE한 내용이 없어졌지만, 

Session 52에서 조회한 데이터로 다른 작업을 진행할 경우 문제가 발생한다.

 

 

잠금을 모른다면.. 참고

https://murphy0v0.tistory.com/16

 

[MSSQL] SQL Server 잠금(LOCK)의 종류

격리 수준에 대해 공부하다가 잠금의 종류를 몰라서 내용 이해가 어려웠다.그래서 격리 수준 공부 중단하고 잠금부터 공부...를.............................. 1. 잠금의 종류1) 공유 잠금 (Shared Lock, S)데

murphy0v0.tistory.com

 

 

 

 

2. READ COMMITTED

다른 트랜잭션에서 수정됐지만 COMMIT 되지 않은 데이터를 읽을수 없도록 지정하는 기본 격리 수준이다.

데이터 조회 시 공유 잠금(S)을 획득하여 조회가 끝나면 반환하기 때문에 Dirty Read가 방지되지만 

Non-Repeatable Read, Phantom Read는 발생한다. 

 

 

 

 

 

 

3. READ_COMMITTED_SNAPSHOT

행 버전관리 기반으로 읽기 작업의 구문이 시작될 때 커밋된 최종 행버전을 저장하여 사용한다.

읽기 작업에서 공유잠금을 필요로 하지 않고, 리소스가 잠겨있어도 기다리지 않아도 된다.

-- READ COMMITTED SNAPSHOPT 변경 구문

ALTER DATABASE [DB명] SET READ_COMMITTED_SNAPSHOT ON

 

장점 : 다른 트랜잭션에 의해 차단되지 않아서 더 많은 동시성이 부여되고, 데이터 잠금을 줄여 성능을 개선한다.

단점 : 버전 저장을 위해 Temp DB에 더 많은 저장 공간이 필요할 수 있고, 복잡한 쿼리에서는 성능이 저하된다.

 

 

 

 

4. REPEATABLE READ

데이터 조회 시 공유 잠금을 획득하고, 트랜잭션이 끝날 때까지 반환하지 않는다.

한 트랜잭션 내에서 읽은 데이터는 항상 같은 값을 읽게 한다.

다른 세션에서 SELECT 는 가능하지만 UPDATE/DELETE를 할 경우 대기 상태가 된다.

범위 조건 검색 시,  INSERT는 수행이 가능하고, 그 결과는 모든 트랜잭션에서 조회가 가능하다.

(Phantom Read의 가능성이 있음.)

 

 

 

 

5. SERIALIZABLE

REPEATABLE READ와 유사하지만, 이 수준은 범위 조건 검색 시 해당 범위에 데이터 삽입도 불가하다.(CUD 모두 불가)

데이터 조회 시 키 단위로 공유 잠금을 하지 않고 키 범위로 잠금을 한다.

동시성은 매우 낮지만 데이터 정합성이 중요한 경우 선택안이 될 수 있다.

Dirty Read, Non-Repeatable Read, Phantom Read 모두 방지된다.

 

 

 

 

6. SNAPSHOT

데이터 상태를 스냅샷으로 저장하여 트랜잭션이 실행되는 동안 다른 트랜잭션의 변경 사항을 보지 않도록 하는 방식.

다른 트랜잭션이 데이터에 대한 변경을 수행하더라도, 현재 트랜잭션은 그 변경 사항을 보지 않는다.

 

그러나 이러한 스냅샷 격리에서 두 개의 트랜잭션이 동시에 같은 데이터를 수정하려고 하면 충돌이 발생할 수 있다.

 

 

 

 

격리 수준 별 발생하는 문제

격리 수준 Dirty Read Non-Repeatable Read Phantom Read
READ UNCOMMITTED O O O
READ CCOMMITTED X O O
REPEATABLE READ X X O
SERIALIZABLE X X X
SNAPSHOT X X X