락
은 두 트랜잭션이 (쓰기, 쓰기)
상황일 때 해결하기 위한 것입니다. 하지만 (읽기, 쓰기)
상황일 때는 갱신손실 같은 심각한 문제는 발생하지 않기 때문에 락을 이용해서 처리하기에는 아쉬운 점이 있습니다. (락으로 해결하면 두 트랜잭션의 동시 진행 정도를 과도하게 막게 됩니다.)
1️⃣ 트랜잭션 동시 실행 문제
- 오손 읽기
- 반복 불가능 읽기
- 유령 데이터 읽기
오손 읽기
읽기 작업을 하는 트랜잭션 1이 쓰기 작업을 하는 트랜잭션 2가 작업한 중간 데이터
를 읽기 때문에 생기는 문제입니다. 작업 중인 트랜잭션 2가 어떤 이유로 작업을 롤백할 경우 트랜잭션 1은 무효가 된 데이터를 읽게 되고
잘못된 결과를 도출합니다.
트랜잭션 2가 age를 21로 변경했다가 롤백을 했습니다. 하지만 트랜잭션 1은 롤백을 하기 전 바뀐 age를 읽었기 때문에 오손 읽기
가 발생하였습니다.
반복 불가능 읽기
반복 불가능 읽기
는 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 갱신하고, 트랜잭션 1이 다시 한번 데이터를 읽을 때 생기는 문제입니다. 즉, 트랜잭션 1이 읽기 작업을 다시 한 번 반복할 경우 이전의 결과가 반복되지 않는 현상
을 반복불가능 읽기라고 합니다.
트랜잭션 1이 데이터를 읽고 작업하던 중 트랜잭션 2가 age를 21로 변경합니다. 트랜잭션 1은 변경된 데이터를 다시 읽어서 작업을 합니다. 트랜잭션 2 또한 정상적으로 COMMIT을 완료했기 때문에 틀린 데이터는 아니지만, 트랜잭션 1 입장에서는 같은 SQL문이 다른 결과를 도출
하게 됩니다.
유령 데이터 읽기
유령데이터 읽기
는 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고, 트랜잭션 1이 다시 한 번 데이터를 읽을 때 생기는 문제입니다. 트랜잭션 1이 읽기 작업을 다시 한번 반복할 경우 이전에 없던 데이터(유령 데이터)가 나타나는 현상
을 유령 데이터 읽기라고 합니다.
반복 불가능 읽기 문제와 비슷하지만, 유령 데이터 읽기는 새로운 데이터가 삽입됩니다. 그래서 이전에 보이지 않았던 데이터가 트랜잭션 2가 종료된 후에 보이는 현상이 발생합니다.
2️⃣ 트랜잭션 고립 수준 명령어
READ UNCOMMITTED
READ UNCOMMITTED는 고립 수준이 가장 낮은 명령어로, 자신의 데이터에 아무런 공유락을 걸지 않습니다
. (배타락은 갱신 손실을 방지하기 위해 걸어야 함)
또한, 다른 트랜잭션에 공유락과 배타락이 걸린 데이터를 대기하지 않고 읽습니다.
READ COMMITTED
READ COMMITTED는 오손 페이지의 참조를 피하기 위해 자신의 데이터를 읽는 동안 공유락을 걸지만
트랜잭션이 끝나기 전에라도 해지 가능합니다. 다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행합니다.
REPEATABLE READ
자신의 데이터에 설정된 공유락과 배타락을 트랜잭션이 종료할 때까지 유지하여 다른 트랜잭션이 자신의 데이터를 갱신할 수 없도록
합니다. 다른 고립 수준에 비해 동시성이 낮아 특별한 상황이 아니라면 사용하지 않는 것이 좋습니다.
SERIALIZABLE
고립 수준이 가장 높은 명령어로, 실행 중인 트랜잭션은 다른 트랜잭션으로부터 완벽하게 분리
됩니다. 데이터 집합에 범위를 지어 잠금을 설정할 수 있기 때문에 다른 사용자가 데이터를 변경하려고 할 때 트랜잭션을 완벽하게 분리할 수 있습니다.
Reference
https://mangkyu.tistory.com/30
https://goodmilktea.tistory.com/62
Uploaded by Notion2Tistory v1.1.0