트랜잭션 격리수준 알아보기

저니·2023년 4월 5일
2

트랜잭션 격리 수준(Isolation Level)이란 데이터베이스에서 여러 트랜잭션이 동시에 수행될 때 각 트랜잭션이 다른 트랜잭션의 어느 정도의 영향을 줄 지 정하는 것을 의미한다. 트랜잭션의 성질(ACID)들 중에서 I(Isolation)에 해당한다.

트랜잭션 성질

Atomicity(원자성)
트랜잭션은 작업의 전체가 수행되거나, 아니면 어떠한 작업도 수행되지 않아야 한다.

Consistency(일관성)
트랜잭션 완료 후에도 데이터베이스가 일관된 상태로 유지되어야 한다.

Isolation(격리성)
트랜잭션은 다른 트랜잭션에 영향을 주지 않도록 격리되어야 한다. 즉, 트랜잭션이 진행 중일 때 다른 트랜잭션에서는 해당 작업에 대한 변경을 수행할 수 없다. 여기서 다른 트랜잭션의 변경을 어느 수준으로 허용할 지 정한 것이 격리 수준이다.

Durability(지속성)
트랜잭션이 성공했다면, 결과는 영구히 반영되어야 한다.

격리 수준이 낮으면 생길 수 있는 문제

격리 수준이 제일 높다면 어떠한 동시성 문제도 일어나지 않겠지만, 그만큼 성능이 떨어지게 된다(모든 Read/Write이 락을 기다려야한다). 그렇다면 격리 수준이 낮을 경우에 어떤 문제가 발생할까?

Dirty Read

Dirty Read는 트랜잭션이 읽은 값이 유효하지 않은 값이란 것을 의미한다.

A x값(=50)을 읽는다.
A x값을 변경(=10)한다.
B x값(=10)을 읽는다
A 롤백 → x의 값은 롤백되어 여전히 50이지만, 트랜잭션 B는 여전히 x가 10임을 가정하고 로직을 수행하게 된다.

Non Repeatable Read

말 그대로 다시 읽었을 때 값이 달라지는 경우다.

A x값(=10)을 읽는다.
B x값을 변경(=30)한다.
B 커밋한다.
A x값을 읽는다(=30) → 이전에 읽었던 값 10과 다른 값을 읽어오게 된다.

Phantom Read

읽었을 때 기존에 없던 값이 새로 나타나는 경우다.
여러 행을 읽는 트랜잭션을 실행할 때, 중간에 행을 삽입하는 트랜잭션이 수행되고 커밋된다면, 다시 행을 읽어올 때 처음에 읽었을 때는 없던 행이 나타나는 경우이다.

A SELECT 문으로 X > 0 인 값을 가져온다. (예를 들어 10개의 행을 읽어왔다)
B X가 10인 행을 삽입한다.
B 커밋한다.
A SELECT 문으로 X > 0 인 값을 가져온다 → 다시 읽어온 행의 수는 10개가 아닌 11개다

Isolation Levels

1. READ UNCOMMITED

트랜잭션이 완료되지 않은(커밋되지 않은) 데이터를 읽을 수 있는 격리 단계.
앞에서 본 3가지 문제가 다 나타난다.

2. READ COMMITTED

커밋된 데이터만 읽을 수 있는 단계. Dirty Read는 발생하지 않고, 나머지 문제는 모두 일어난다.

A x값(=50)을 읽는다.
A x값을 변경(=10)한다.
B x값(=10)을 읽으려고 하지만 아직 커밋되지 않았으므로 대기한다.
A 롤백 → A가 롤백되어 트랜잭션이 종료되었으므로 B는 x값을 제대로 읽어올 수 있다

3. REPEATABLE READ

한 트랜잭션이 읽기 연산만을 수행할 때도, 다른 트랜잭션이 쓰기를 허용하지 않기 때문에 읽는 동안 해당 값이 변경되지 않는다(Read 락이 Write락도 블락한다).

A x값(=10)을 읽는다.
B x값을 변경(=30)하려고 하지만 A가 락을 가지고 있으므로 변경하지 못하고 대기한다.
A x값(=10)을 다시 읽는다.
A 커밋한다
B x값을 변경한다. → A가 커밋되어 트랜잭션이 종료되었으므로 B는 x값을 변경할 수 있다

하지만 해당 트랜잭션에서 읽는 값이 아닌 다른 행에 대해서 삽입은 허용하기 때문에 Phantom Read는 발생하게 된다.

4. SERIALIZABLE

가장 높은 격리 수준이고, Phantom Read도 발생하지 않는다.
트랜잭션이 조작하는 모든 행의 범위에 대해 락을 걸기 때문에 행을 삽입하는 경우에도 경우에도 대기해야 한다.

격리 수준에 따라 생길 수 있는 문제 정리

Isolation LevelDirty ReadNon Repeatable ReadPhantom Read
READ UNCOMMITED발생발생발생
READ COMMITED-발생발생
REPEATABLE READ--발생
SERIALIZABLE---

0개의 댓글