개념
Isolation Level 은 데이터베이스의 트랜잭션 격리 수준을 얘기합니다.
이는 여러 트랜잭션이 동시에 실행되고 있을 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나, 조회하는 데이터를 볼 수 있게 허용하는 여부를 결정하는 것입니다.
Serializable
가장 엄격한 격리 수준입니다. 이름 그대로 트랜잭션을 순차적으로 진행시킵니다.
여러 트랜잭션이 동시에 진행 될 일이 없어서 데이터 부정합 문제가 발생되지 않지만, 트랜잭션을 순차적으로 진행하기 때문에 동시 처리 속도가 현저히 떨어지게 됩니다.
Repeatable Read
Repeatable Read 는 언두 로그를 활용하는 트랜잭션 격리 수준입니다.
📢 언두 로그가 뭘까요?
일반적인 RDBMS 는 변경 전의 레코드를 언두 공간에다가 백업합니다. 이렇게 되면 변경 전 / 후 의 데이터가 모두 존재 하는데, 이를 MVCC(Multi Version Concurrency Control, 다중 버전 동시성 제어) 라고 합니다.
MVCC 를 통해서 트랜잭션 롤백된 경우, 데이터를 복원할 수 있을뿐만 아니라, 서로 다른 트랜잭션 간에 접근할 수 있는 데이터를 세밀하게 제어할 수 있게 됐습니다.
각각의 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호가 존재하며, 백업 레코드에는 몇번 트랜잭션에서 백업되었는지 트랜잭션 번호를 함께 저장합니다.
Repeatable Read 는 언두 로그와 MVCC 를 사용하여 동일한 트랜잭션 내에서 읽은 데이터가 변경되지 않도록 보장합니다. 즉, 트랜잭션 시작 이후 읽은 데이터가 트랜잭션 끝날 때까지 변경되지 않도록 해줍니다.
📢 동일한 트랜잭션 내에 읽은 데이터가 변경되지 않는게 무슨 뜻일까요?
1. Transaction 1: 민수라는 레코드만 있는 데이터를 읽고 트랜잭션 시작
2. Transaction 2: 민수라는 레코드를 홍원으로 변경 후 커밋 및 트랜잭션 종료
3. Transaction 1: 아직 트랜잭션을 종료하지 않고, 다시 데이터를 읽어옴, 이때 민수라는 레코드만 볼 수 있음
왜 이렇게 될까요? Transaction 1 은 다시 데이터를 읽어올 때 언두 로그에 있는 Transaction 1 번 데이터를 읽어오기 때문입니다.
새로운 레코드 추가에 대한 보장은 없습니다. Serializble 이 아닌 모든 격리 수준에서는 Phantom Read 라는 현상이 발생하기 때문입니다.
📢 팬텀 리드 (Phantom Read) 가 발생하는 상황 예시를 한번 볼까요?
1. Transaction 1: 민수라는 레코드만 있는 데이터를 읽고 트랜잭션 시작
2. Transaction 2: 홍원이라는 새로운 레코드를 추가하고 트랜잭션을 종료
3. Transaction 1: 아직 트랜잭션을 종료하지 않고, 다시 데이터를 읽어옴, 이때 민수와 홍원이라는 레코드를 모두 볼 수 있음
하지만 일반적으로 MVCC 덕분에 팬텀 리드는 발생하지 않습니다. 새로 들어온 레코드는 무시하면 되거든요.
그럼 팬텀 리드는 언제 발생할까요? 락을 사용할 때 발생합니다.
Read Committed
말 그대로 커밋 된 레코드만 조회할 수 있습니다.
Repeatable Read 랑 다르죠?
📢 Read Committed 는 어떤 방식으로 동작할까요?
1. Transaction 1: 민수라는 레코드만 있는 데이터를 읽고 트랜잭션 시작
2. Transaction 2: 민수라는 레코드를 홍원으로 변경 후 커밋 및 트랜잭션 종료
3. Transaction 1: 아직 트랜잭션을 종료하지 않고, 다시 데이터를 읽어옴, 이때 홍원이라는 변경된 (커밋된) 레코드를 볼 수 있음
Read Committed 는 Non-Repeatable Read(반복 읽기 불가) 문제가 일어납니다.
위에 설명했던 Repeatable Read 격리 수준에 Non- 만 붙인 거에요
같은 트랜잭션인데도 조회를 할 때마다 데이터가 달라지면 데이터를 다룰 때 다양한 문제가 일어 날 수 있습니다.
예를 들어 입금된 총합을 계산하는 트랜잭션이 돌아가고 있는데, 다른 트랜잭션에서 계속해서 입금을 하는 상황이 있다고 가정하면 입금 총합이 입금 내역이랑 차이가 생길 수도 있습니다.
Read Uncommitted
커밋이 안된 레코드도 조회할 수 있습니다.
가장 위험한 격리 수준입니다. 그냥 안 쓰는 게 좋아요
📢 Read Uncommitted 는 어떤 방식으로 동작할까요?
1. Transaction 1: 민수라는 레코드만 있는 데이터를 읽고 트랜잭션 시작
2. Transaction 2: 민수라는 레코드를 홍원으로 변경
3. Transaction 1: 아직 트랜잭션을 종료하지 않고, 다시 데이터를 읽어옴, 이때 홍원이라는 변경된 (커밋이 안된) 레코드를 볼 수 있음
4. Transaction 2: 문제가 생겨서 롤백 됨
5. Transaction 1: 아직 트랜잭션을 종료하지 않고, 다시 데이터를 읽어옴, 이때 민수라는 변경된 (롤백된) 레코드를 볼 수 있음
'CS > DB' 카테고리의 다른 글
오프셋 기반 페이지네이션은 왜 느린가요? (0) | 2024.12.22 |
---|---|
Ordered UUID 대체 키 사용 (1) | 2024.04.19 |
관계 (0) | 2024.03.17 |
필드와 레코드 (0) | 2024.03.17 |
도메인 (0) | 2024.03.10 |