트랜잭션 격리 수준
개요
위키문서를 들어가보면 누구나 기여할 수 있는 문서라는 문구가 나온다. 이렇게 한 번 생각해보자.
A유저가 데이터를 읽는다. 그와 동시에 B 유저는 해당 데이터를 수정한다.
A가 본 데이터는 수정 전 데이터인데, 잠시 후 A가 다시 수정하려고 하면 충돌이 일어난다.
어떻게 될까?
우선 이런 상황에서 발생할 수 있는 문제를 살펴보자.
하나의 트랜잭션 안에서 크게 3가지 문제가 발생한다.
Dirty Read: B유저가 수정중인 데이터를 볼 수 있고 만약 B가 수정을 취소한다면 A가 본 데이터는 실제로는 존재하지 않는 데이터가 된다. 그럼 A는 존재하지 않는 데이터를 기반으로 작업을 하게된다. Non-repeatable Read: B가 문서를 수정하기 시작한다. 그러는 중 A가 문서를 조회한다. B가 저장을 하지 않았다면 A가 읽는 것은 B가 수정하기 전 내용이다. 그러다 B가 수정을 완료하고 다시 조회하면 결과가 달라질 수 있다. Phantom Read: B 유저가 새로운 페이지를 추가 또는 삭제했다. A가 같은 조건으로 문서를 조회했더니 결과가 달라진다.
데이터베이스 수준 제어
트랜잭션 격리 수준
데이터베이스는 다음과 같은 전략을 제공한다.
READ UNCOMMITTED: 커밋되지 않은 데이터도 조회할 수 있다.
READ COMMITTED 방법은 가장 낮은 격리 수준으로 DirtyRead를. 허용한다. 즉 다른. 트랜잭션이 커밋하지 않은 데이터도 읽을 수 있는데 성능상 가장 뛰어나지만 데이터 일관성 보장이 어렵다는 단점이 있다.
REPEATABLE READ는 두 번째 문제를 해결한 방법으로 같은 트랜잭션 내에서는 같은 결과만 보인다. 그리고 새로운 트랜잭션을 시작하면 그 때서야 변경사항이 보인다.
SERIALIZABLE: 가장 높은 격리 수준으로 모든 읽기/쓰기 충돌을 방지한다. 이는 말 그대로 병렬의 요청을 일직선 상에 놓는 것과 같다. 이렇게 하면 팬텀 리드를 방지할 수 있다.