데이터는 일관성있게 제공되어야 한다.
SQL문이 수행되는 도중에 다른 트랜잭션에 의해 데이터가 변경,추가,삭제 되었을떄,
이를 반영한다면 일관성 없는 결과집합을 리턴 할 것이다.
오라클에서는 이를 방지하기 위해 사용하는 '문장 읽기 일관성'이 있다.
오라클은 다른 트랜잭션의 영향을 받지않고 일관성있게 결과집합을 구할때 Undo 세그먼트를 활용한다.
오라클만 그런가요?
다른 DBMS는 로우lock (해당 레코드에 대한 잠금) 을 사용해 dirty read를 방지한다. 읽기작업에 대해서는 shared lock(공유 락) 을사용하여 exclusive lock(베타적 락)이 걸린 로우를 읽지못한다.
하지만 이것으로는 완벽한 일관성을 주지못하며 테이블 lock이나 트랜잭션 고립화 수준을 높여 완벽하게 보장 할 수 있다.
이는 반대로 동시성이 급격하게 떨어지며, 성능에서 아쉬운 모습을 보인다.
오라클은 Undo 세그먼트를 활용해 각데이터를 일관성있는 데이터인지 검사하여 완벽한 문장수준 읽기 일관성을 보이며, 동시성도 확보한다
Consistent(시작 시점) 모드 블록 읽기
Consistent모드는 쿼리가 시작된 시점을 기준으로 데이터를 읽고,
SCN이라는 시간정보를 이용해 일관성있는 데이터인지 검사한다.
블록이 마지막으로 변경된 시점을 블록 헤더에 SCN정보로 입력하는데 이를 비교한다.
위 그림처럼 시작 시점(SCN 123) 으로 데이터를 읽다가 SCN138을 만나면 즉시
Current블록(디스크에서 읽혀진 최종 원본) 의 복사본인 cr 블록을 생성한다.
cr 블록의 SCN을 비교하여 시작 시점과 같거나 작으면 일관성있게 읽을 수 있는 알고리즘이다.
이처럼 테이블lock 하지않아도 완벽한 일관성을 제공하고 동시성도 확보한다.
Current(현재 시점) 모드 읽기
Current모드는 SQL문이 시작된 시점이 아니라 데이터를 찾아간 바로 그 시점의 최종 값을 읽는 것을 말한다.
SCN이 높고 낮음을 따지지않고 그시점에 커밋된 값이라면 그대로 읽는다.
Consistent 모드로 갱신 대상을 식별하고 Current모드로 갱신
update문은 select, update 로 크게 나뉜다.
두 모드의 동작 과정이다.
consistent가 필요한 이뉴는 시작 시점 기준으로 대상을 식별하려고 사용할 뿐이며, 갱신이 진행되는 동안 추가되거나 범위 안에 새로들어오는 레코드를 제외하고자 하는것 이다.
정리하면
select는 consistent로 읽는다.
insert, update, delete, merge는 current모드로 읽고 쓴다. 다만 갱신 대상 식별작업은 consistent모드로 이루어 진다.