트랜잭션은 다른 트랜잭션에서 동시에 변경한 데이터를 읽거나 두 트랙잭션이 동시에 같은 데이터에 변경하려고 할때 나타나며, 타이밍에 운이 없을때만 촉발되기 때문에 테스트로 발견하기가 어렵다.
따라서 데이터베이스는 트랜잭션 격리를 제공함으로써 동시성 문제를 애플리케이션 개발자들에게 감췄다.
보장하는 것
더티 읽기란(Dirty Read)?
다른 트랜잭션에서 커밋되지 않은 데이터를 보는 것
트랜잭션이 쓴 내용은 커밋된 후에야 다른 트랜잭션에게 보인다는 뜻
set x =3, set y=2 가 하나의 트랜잭션에 묶여있기 때문에 사용자가 두번쨰 get X를 했을때도 2가 반환되며 사용자 1의 트랜잭션이 끝난 이후에 get x 했을때 3의 값을 얻을 수 있다.
더티 읽기 방지를 하는 이유?
트랜잭션이 abort되면 이전 내용들은 모두 롤백 되어야 하는데 데이터베이스가 더티 읽기를 한다면 데이터베이스에 커밋되지 않을 데이터를 볼 수 있고 이는 데이터 무결성을 해칠 수 있다.
더티 쓰기란?
먼저 쓴 내용이 아직 커밋되지 않은 사애태에서 나중에 실행된 쓰기 작업이 커밋되지 않은 값을 덮어써버리는 상황이다.
먼저 쓴 트랜잭션이 커밋되거나 어보트 될 떄까지 두 번째 쓰기를 지연시키는 방법을 사용한다.
더티 쓰기를 방지하는 이유
위 그림의 경우 밥과 엘리스가 동시에 같은 차를 사려고 한다. 자동차는 밥에게 판매 됐지만 송장은 엘리스에게 전송됐다.
더티 쓰기가 가능하면 다른 트랜잭션에서 충돌하는 쓰기를 실행할 때 내용이 섞일 수 있다.
흔한 방법으로 데이터베이스는 로우 수준 잠금을 사용해 더티 쓰기를 방지한다.
트랜잭션에서 특정 객체를 변경하고 싶다면 해당 객체에 대한 잠금을 획득해야 한다.
그러나 이 방법은 읽기만 실행하는 여러 트랜잭션들이 오랫동안 실행되는 쓰기 트랜잭션 하나가 완료될 때까지 기다려야 하는 상황이 생길 수 있디 때문에 현실에서는 잘 동작하지 않는다
My SQL, PostgressSQL 에서는 REAPEATABLE READ(반복 읽기)라고 부른다. (같은 개념)
non-repeatable Read(비반복 읽기)문제르 해결하기 위한 해결책이며,
각 트랜잭션은 데이터베이스의 일관된 스냅숏으로부터 값을 읽는다.
다시 말해 트랜잭션은 시작할 때 데이터베이스의 커밋된 상태의 모든 데이터를 본다.
데이터가 다른 트랜잭션에 의해 변경되더라고 각 트랜잭션은 특정한 시점의 과거 데이터를 보게 된다.
읽는 쪽에서 쓰는 쪽을 차단하지 않고, 쓰는 쪽에서도 읽는 쪽을 차단하지 않는다는 것, 이를 통해 데이터베이스는 잠금 경쟁 없이 쓰기 작업이 처리됨과 동시에 일관성 있는 스냅숏에 대해 오래 실행되는 읽기 작업을 처리할 수 있다.
다중 버전 동시성 제어(multi-version concurrency, MVCC)
진행 중인 여러 트랜잭션에서 서로 다른 시점의 데이터베이스 상태를 봐야할 수 있기 때문에 데이터베이스가 객체의 여러버전을 유지하는 기법이다.
데이터베이스가 커밋 후 읽기 격리만 제공한다면 MVCC가 필요하지 않고 객체마다 두개의 버전(커밋된 버전, 덮어 쓰여졌지만 아직 커밋되지 않은 버전)만 유지하면 충분하다.
면접에 나오면 좋겠네요