!! 글을 읽기 전 필독 !!
DBMS 마다 격리 수준에 대한 내용이 다를 수 있으니 보다 정확하게 알기 위해서는 공식 문서를 확인해야 한다. 필자는 MySQL 에서 제공하는 격리수준을 기준으로 하였다. 참고로 MySQL의 기본 격리수준은 Repeatable Read이다.
여러 트랜잭션이 동시에 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것이다.
Isolation Level에 대한 조정은, 동시성과 데이터 무결성에 연관되어 있음
즉 상황에 따라 처리해야하는 데이터 특성이 다를 것이다. 따라서 트랜잭션 격리 수준을 각 Level로 나누어 상황에 따라 동시성이 높은 Level, 데이터 무결성이 높은 Level을 선택할 수 있게 하기위해 존재한다.
커밋되지 않은 수정중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생하는 현상
어떤 트랜잭션에서 아직 실행이 끝나지 않은 상황에서 다른 트랜잭션에 의한 변경사항을 보게되는 경우
1. DB에는 10만원을 가지고 있는 계좌가 있다.
2. Transaction A는 DB에 Read 요청을한다. ->계좌의 10만원 확인
3. Transaction A는 DB에 5만원 입금 Write 요청을한다. -> DB의 계좌는 15만원이 됨
4. Transaction A의 Commit은 완료되지 않았는데 Transaction B가 DB에 Read가 가능하다.
5. Transaction B는 15만원의 계좌금액을 확인한다.
6. 이 때 Commit이 완료되지 않은 Transaction A에 Rollback이 생겨 DB의 계좌는 10만원이 된다.
7. 즉 DB에는 10만원이 있는데 Transaction B는 15만원이 조회되는 DIRTY-READ 상황이 발생함
하지만 데이터가 잘 처리되어서 RollBack이 안 되었다면 동시에 데이터를 처리했기 때문에 빠른 성능을 보이게 되었을 것임, 즉 DB의 일관성, 고 신뢰성을 낮지만 성능은 높을 것을 확인할 수 있다.
트랜잭션 내에서 같은 데이터를 여러 번 조회할 때 읽은 데이터가 서로 다른 값으로 나오는 문제
1, DB에는 10만원을 가지고 있는 계좌가 있다.
2. Transaction A는 DB에 Read 요청을한다. ->계좌의 10만원 확인
3. Transaction A는 DB에 5만원 입금 Write 요청을한다. -> DB의 계좌는 15만원이 됨
4. Transaction A의 Commit은 완료되지 않아서 Transaction B는 Transaction A 실행 전 데이터인 10만원을 읽어 옴
5. Transaction A 가 Commit을 완료하고, Transaction B가 다시 Read하면 15만원을 읽어온다.
6. 즉 Transaction B는 같은 DATA를 읽기 요청을 헀는데 서로 다른 DATA가 나오며 문제 발생
여기서 헷갈렸는데 이해한 부분은 Transaction B내에서 Read 요청을 2번 이상 했을 때 다른 Data가 Read된다는 것이었다.
한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽었을 때, 첫번째 쿼리에서 없던 레코드가 두번째 쿼리에서 나타나는 현상
트랜잭션 도중 새로운 레코드 삽입을 허용하기 때문에 나타나는 현상임
레코드가 추가된 상황에는 Repeatable Read가 적용되지 않아 동일한 값이 보장되지 않은 것임
1. Transaction A Commit이 완료된다.
2. Transaction B가 실행된다.
Read Committed : 아직 커밋되지 않은 데이터를 읽을 수 있다.
Read Committed: 커밋된 데이터만 읽을 수 있다.
Repeatable Read: 특정 데이터를 반복조회시 같은 값을 반환한다.
Serializable: 트랜잭션이 순차적으로 실행된다.