[Database] Isolation Level

Bik_Kyun·2022년 5월 1일
0
post-thumbnail

1. Isolation Level

트랜잭션 격리수준(Isolation Level)이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다.

즉, 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정한다.

데이터베이스는 ACID 특징과 같이 트랜잭션이 독립적인 수행을 하도록 Locking을 통해, 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하도록 막는 것이 필요하다.

하지만 무조건 Locking을 사용하여 동시에 수행되는 수많은 트랜잭션들을 순서대로 처리하는 방식으로 구현하게 되면 데이터베이스의 성능은 떨어지게 된다. 하지만, 성능을 높이기 위해 Locking의 범위를 줄인다면 잘못된 값이 처리될 문제가 발생할 수 있다.

✅ 잠금(Lock) - 동시성 제어

DB관리에서 하나의 트랜잭션에 사용되는 데이터를 다른 트랜잭션이 접근하지 못하게 하는 것
⓵ 잠금 -> 실행 -> 해제
로킹 단위가 크면 잠금 로킹 수가 작아 관리하기 쉽지만 공유성이 낮아지고 로킹 단위가 작으면 로킹 수가 많아 관리하기 복잡하지만 공유성이 높아진다.
⓷ 교착 상태 = 잠가 놓은 자원을 모든 트랜잭션들이 무한정 대기하는 상태, 한 트랜잭션을 RollBack하고 나머지 하나를 완료시킨 후 RollBack한 트랜잭션을 다시 실행시켜 해결한다.

따라서 효율적인 Locking 방법이 필요하다.

  • Shared Lock(공유 잠금) : 데이터를 읽을 때 사용되어지는 Lock.
    공유 잠금은 공유 잠금끼리 동시에 접근이 가능하다.
    하지만, 공유 잠금이 설정된 데이터에는 배타 잠금을 사용할 수는 없다.
  • Exclusive Lock(배타 잠금) : 데이터를 변경하고자 할 때 사용되며 트랜잭션이 완료될 때까지 유지된다.
    잠금이 해제될 때까지 다른 트랜잭션(읽기 포함)은 해당 리소스에 접근할 수 없다.
    해당 잠금은 트랜잭션이 수행되고 있는 데이터에 대해서는 접근하여 함께 잠금을 설정할 수 있다.

2. Isolation Level의 종류

1) READ UNCOMMITTED

  • 가장 낮은 고립 수준
  • SELECT 문장이 수행되는 동안 해당 데이터에 Shared lock을 걸지 않고 데이터를 읽는다.
  • 데이터베이스의 일관성을 유지하는 것이 불가능하다.
  • Dirty Read(오손 데이터 읽기) 발생
    A 트랜잭션에서 나이를 27을 28로 변경 후 COMMIT을 하지 않은 상태에서 B 트랜잭션이 나이를 조회할때 28이 조회가 된다.(Dirty Read) 이후, A 트랜잭션에서 ROLLBACK을 수행하더라도 B 트랜잭션은 나이를 28이라고 생각하고 로직을 수행한다. 결과적으로 데이터 정합성에 문제가 생긴다.

SET TRANSACTION READ WRITE
ISOLATION LEVEL READ UNCOMMITTED;

2) READ COMMITTED

  • 읽기가 수행되는 동안 해당 데이터에 Shared Lock이 걸린다. 읽기가 끝나자 마자 Lock는 해제된다.
  • 갱신하려는 데이터에는 Exclusive Lock이 걸리고 트랜잭션이 끝날 때까지 유지한다.
  • 트랜잭션이 수행되는 동안 다른 트랜잭션이 접근할 수 없어 대기하게 된다.
  • COMMIT이 이루어진 트랜잭션만 조회 가능
  • Oracle DB, SQL Server에서 기본적으로 사용되는 Isolation Level이다.
  • Non-Repeatable Read 발생
    B 트랜잭션에서 나이를 조회하니 27이라는 결과가 나왔다. 이 때, A 트랜잭션이 나이를 28로 변경하고 COMMIT한다. 다시 B 트랜잭션이 나이를 조회하게되면 28이라는 결과가 나온다.

SET TRANSACTTION READ WRITE
ISOLATION LEVEL READ COMMITTED;

3) REPEATABLE READ

  • SELECT되는 데이터에 대해 Shared Lock을 걸고 트랜잭션이 끝날 때까지 유지한다.
  • 갱신하려는 데이터에 대해서는 Exclusive Lock이 걸리고 트랜잭션이 끝날 때까지 유지한다.
  • 한 트랜잭션 내에서 동일한 질의를 두 번 이상 수행할 때 결과가 항상 동일함을 보장한다.
  • 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정이 불가능하다.
  • Non-Repeatable Read 부정합이 발생하지 않음
    10번 트랜잭션이 100번 사원을 조회한다. 12번 트랜잭션이 100번사원의 이름을 조회하고 변경한 후 COMMIT한다. 10번 트랜잭션이 100번 사원을 다시 조회하면 undo 영역에 백업된 데이터를 반환한다.
  • 자신의 트랜잭션 번호보다 낮은 트랜잭션 번호에서 COMMIT된 것만 보게 된다.
    모든 InnoDB의 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 갖고 있으며 undo 영역에 백업된 모든 레코드는 변경을 발생시킨 트랜잭션의 번호를 포함하고 있다.
  • MySQL에서 사용되는 Isolation Level.
  • Phantom Read 발생
    한 트랜잭션이 일정 범위의 데이터를 여러 번 읽을 때, 다른 트랜잭션에 의해 새로운 데이터로 갱신되어 쿼리 수행 결과가 다르게 나오는 현상.

SET TRANSACTION READ WRITE
ISOLATION LEVEL REPEATABLE READ;

4) SERIALIZABLE

  • 가장 높은 고립 수준
  • SELECT되는 투플들 뿐만 아니라 인덱스에 대해서도 Shared Lock를 걸고 트랜잭션이 끝날 때까지 유지한다.
  • 갱신하려는 데이터에 대해서는 Exclusive Lock를 걸고 트랜잭션이 끝날 때까지 유지한다.
  • 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능하다.

SET TRANSACTION READ WRITE
ISOLATION LEVEL SERIALIZABLE;

profile
비진

0개의 댓글