(Isolation level)
트랜잭션의 특징 ACID 중 Isolation에 따라, 트랜잭션간에 격리성(독립성)을 완전히 보장해야 합니다. 하지만 그럴 경우를 완전히 보장하기 위해서는 모든 트랜잭션을 차례로 처리 해야 하고, 이는 성능의 하락으로 이어집니다.
트랜잭션 격리 수준은, 동시에 여러 트랜잭션이 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것입니다.
0 : READ UNCOMMITTED
(커밋되지 않은 읽기)DIRTY READ
트랜잭션이 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있게 되는 현상
💡 예시
트랜잭션 A
가 실행되고 update 됐을 때 그 사이에트랜잭션 B
가 실행된다.
그러면트랜잭션 A
에서 커밋이 되지 않았음에도 불구하고,트랜잭션 B
에서트랜잭션 A
가 update한 내용을 확인할 수 있게 된다.
1 : READ COMMITTED
(커밋된 읽기)COMMIT 이 된 데이터만 읽습니다.
RDB에서 대부분 기본적으로 사용되고 있는 격리 수준
Dirty Read와 같은 현상은 발생하지 않지만 NON-REPEATABLE READ 발생
NON-REPEATABLE READ
하나의 트랜잭션 내에서 동일한 SELECT 쿼리를 실행했을 때 항상 같은 결과를 보장해야 한다는 REPEATABLE READ 정합성에 어긋나는 것
💡 예시
트랜잭션 A
에서 update 된 내용이 타 트랜잭션에서 바로 보여지지는 않는다. 근데트랜잭션 A
에서 커밋이 완료되었는데트랜잭션 B
에는 아직 완료되지 않은 경우,트랜잭션 B
에서 다시 한번 조회를 하게 된다면 update 된 상태가 조회가 된다
같은 조회(셀렉트)문인데도 결과가 다르기 때문에 정합성에 어긋난다.
실제 테이블 값을 가져오는 것이 아니라 Undo 영역에 백업된 레코드에서 값을 가져온다.
UNDO 영역:
간단하게 데이터를 저장하는 버퍼 기능을 한다고 보면 되고, 트랜잭션에서 연산(커밋 롤백)이 이루어지지 않아도 질의문에 의해 수정이 생기면 수정되기 이전 값이 저장되는 영역
2 : REPEATABLE READ
(반복 가능한 읽기)PHANTOM READ
다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다가 안 보였다가 하는 현상
💡 예시
같은 테이블에 접근하는 여러개의 트랜잭션을 처리하고 있습니다. 그중 한 트랜잭션이SELETE ~~ FOR UPDATE
을 사용하여 쓰기 잠금을 걸고 싶다고 가정합니다. 쿼리문에 따라, SELECT하려는 레코드에 쓰기 잠금을 걸어야 하는데, Undo 레코드에는 잠금을 걸 수 없습니다. 따라서 위와 같은 쿼리는 Undo 영역의 변경 전 데이터를 가져오는 것이 아니라 현재 레코드의 값을 가져오게 됩니다! 따라서 레코드가 보였다 안보였다 한다고 해서 🎭 PHANTOM 이라고 합니다.
REPEATABLE READ 추가 설명
모든 트랜젝션은 번호를 갖고, undo영역에서는 트랜잭션 번호를 함께 보관합니다.
아까와 같이트랜잭션 A
와트랜잭션 B
가 있습니다.트랜잭션 A
의 번호는 13번이고트랜잭션 B
의 번호는 10번입니다.
트랜잭션 B
가 시작했습니다.
➡트랜잭션 A
에서는 일부 값을 업데이트 하고 커밋하였습니다.
➡트랜잭션 B
안에서 실행되는 모든 SELECT 쿼리는 자신의 트랜잭션인 10번 보다 작은 트랜잭션 번호에서 변경한 것만 보게 됩니다. 즉, 번호가 13인트랜잭션 A
에서 변경한 내용은 10번인트랜잭션 B
에 영향을 주지 않습니다. 이는 Undo 영역에 트랜잭션 번호가 저장되어있기 때문에 가능한 것입니다.
3 : SERIALIZABLE
(직렬화 가능)(+) 트랜잭션 격리 수준에 따른 동시성과 일관성 변화
사진 출처
격리 수준이 높아지면서 데이터의 일관성이 유지될 수 있지만, 동시에 처리가능한 트랜잭션의 양은 떨어집니다. 격리수준이 낮아지면 일관성은 유지되기 어렵지만, 동시에 처리할 수 있는 트랜잭션의 양은 늘어나게 됩니다.
- 동시성 : 동시에 수행하는 트랜잭션 양
- 일관성 : 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것