트랜잭션의 격리 수준에는 4 가지가 있다. 두 tx A, B가 함께 begin해서 동시에 진행된다고 생각하고 낮은 수준부터 차례대로 문제점을 짚어본다. 당연히 낮은 레벨은 상위 레벨의 문제점을 포함하며, 간략한 설명을 위해 나만의 pseudo 쿼리로 설명한다.
1. dirty read
A - insert x (not committed)
B - select * -> x가 보임
dirty read
2. read commited
A - insert x, commit
A - update x set a
B - select * -> commit 전이므로 a가 보인다.
A - commit
B - select * -> commit 이후이므로 x가 보인다. tx B는 조회할때마다 다른 결과를 볼 수 있는 문제가 있다.
non-repeatable reads
3. repeatable read (MySQL을 제외한 대부분 DB는 기본적으로 read committed이고, for update 구문을 쓰면 repeatable read가 된다.)
B - select count(*) -> 3이 나왔다면,
A - insert x, commit
B - select count(*) -> 4가 나온다. (A의 commit 이후 새 row가 보인다. 조회할때마다 추가된 row가 보일 수 있는 문제가 있다.)
phantom reads
4. serializable
없음
아래는 예제를 이해하기 쉽게 그림으로 잘 나타낸 글이다.
https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation
undo segment 사용법에 따라 레벨이 나눠지는데, read committed라고 해서 undo segment에 txid를 저장하지 않을리는 없다. 다만 repeatable read를 하게되면 특정 xid 이전까지 undo record chain을 쭉 따라가야 하는 overhead가 있고, undo retention이 끝나서 실패할 위험도 있다. 그래서 다들 read committed를 쓰는 듯 하다.
'backend' 카테고리의 다른 글
oracle golden gate 19c 예제 (0) | 2020.08.28 |
---|---|
Kafka의 exactly-once semantic (0) | 2019.11.21 |
분산 데이터베이스의 CAP 이론 (0) | 2019.08.31 |
Load Balancer (0) | 2019.08.03 |