transaction들이 동시에 실행될 때 발생 가능한 이상 현상들
Dirty read : commit 되지 않은 변화를 읽음
예시) x = 10, y = 20
Transaction 1 : x에 y를 더한다
Transaction 2 : y를 70으로 바꾼다
Transaction 1 | Transaction 2 |
read(x) ⇒ 10 | |
write(y = 70) | |
read(y) ⇒ 70 | |
write(x = 80) | |
commit | |
abort : rollback(y = 20) |
이 결과 x = 80, y 는 rollback되서 20이 되는데, commit되지 않은 y값을 읽고 진행한 transaction1 도 이상한 값이 된다
Non-repeatable read(=Fuzzy read) : 같은 데이터의 값이 달라짐
예시) x = 10
Transaction 1 : x를 두번 읽는다
Transaction 2 : x에 40을 더한다
Transaction 1 | Transaction 2 |
read(x) ⇒ 10 | |
read(x) ⇒ 10 | |
write(x = 50) | |
commit | |
read(x) ⇒ 50 | |
commit |
Phantom read : 없던 데이터가 생김
예시) t1(…, v=10), t2(…, v=10)
Transaction 1 : v가 10인 데이터를 읽는다
Transaction 2 : t2의 v를 10으로 바꾼다
Transaction 1 | Transaction 2 |
read(v = 10) ⇒ t1 | |
write(t2.v = 10) | |
commit | |
read(v = 10) ⇒ t1, t2 | |
commit |
문제점 : 위의 Dirty read, Non-repeatable read, Phantom read 등 이상한 현상들이 발생하지 않게 할 순 있지만 그러면 제약사항이 많아져서 동시 처리 가능한 트랜잭션 수가 줄어들어 결국 DB의 전체 처리량이 하락하게 된다
해결책 : 일부 이상한 현상은 허용하는 몇가지 level을 만들어서 사용자가 필요에 따라 적절하게 선택할 수 있도록 하자!
Isolation level
개발자들은 isolation level을 통해 전체 처리량과 데이터 일관성 사이에서 어느 정도 거래를 할 수 있다
standard SQL 92 isolation level 비판
- 세가지 이상 현상의 정의가 모호하다
- 이상 현상은 세가지 외에도 더 있다
- 상업적인 DBMS에서 사용하는 방법을 반영해서 isolation level을 구분하지 않았다
다양한 이상현상 케이스들
Dirty write : commit안된 데이터를 write함
한 트랜잭션이 commit되지 않은 다른 트랜잭션이 write한 데이터를 write작업하면서 나타나는 이상현상
rollback시 정상적인 recovery는 매우 중요하기 때문에 모든 isolation level에서 dirty write를 허용하면 안된다.
Lost update : 업데이트를 덮어 씀
한 트랜잭션이 abort 혹은 commit되면서 다른 트랜잭션이 commit하여 업데이트한 결과가 사라지는 현상
예시) x = 50
Transaction 1 : x에 50을 더한다
Transaction 2 : x에 150을 더한다
Transaction 1 | Transaction 2 |
read(x) ⇒ 50 | |
read(x) ⇒ 50 | |
write(x = 200) | |
commit | |
write(x = 100) | |
commit |
Dirty read 의 확장: commit 되지 않은 변화를 읽음 → abort가 발생하지 않아도 dirty read가 될 수 있다
Read skew : inconsistent한 데이터 읽기
- 한 트랜잭션에서 관련 있는 서로다른 데이터를 읽었는데 데이터 일관성이 깨지는 현상
- x=50, y=50 인 데이터를 읽을때 tx2가 x=50을 읽은 후, 다른 tx1에서 x가 y에 40을 이체하고 커밋을 했다. 이후 tx2가 y를 읽으면 y=90인데 x는 이전에 읽어둔 50이므로 데이터의 일관성이 깨지게 된다
Write skew : inconsistent한 데이터 쓰기
- 두 트랜잭션에서 관련있는 서로 다른 데이터에 쓰기 작업을 진행했는데 데이터 일관성이 깨지는 현상
Phantom read 확장 : 같은 조건으로 데이터를 여러번 읽는 경우가 아니더라도 phantom read가 발생한다
Snapshot isolation
: 어떻게 concurrency control을 구현할 것인지, 이 구현 방식에 기반해서 정의된 isolation level
예시) x = 50, y = 50
Transaction 1 : x가 y에 40을 이체한다
Transaction 2 : y에 100을 입금한다
Transaction 1 | Transaction 2 |
read(x) ⇒ 50 | |
write(x = 10) | |
read(y) = 50 | |
write(y = 150) | |
commit | |
read(y) ⇒ 50 | |
write(y = 90) | |
abort |
트랜잭션 시작시 데이터를 snapshot 찍듯이 그 시점 데이터상태를 읽어오기 때문에 transaction1이 y를 읽었을때 값은 50이다. 이후 y값을 commit하려고 보니 이미 y에 commit된 transaction2가 있기 때문에 transaction1은 abort되어 폐기된다
Snapshot isolation type of MVCC(multi version concurrency control)
- transaction 시작 전에 commit된 데이터만 보임
- First-committer win
출처: 쉬운코드
'STUDY > database' 카테고리의 다른 글
[DB] MVCC 설명_1 (쉬운코드) (0) | 2023.12.19 |
---|---|
lock을 활용한 concurrency control (0) | 2023.12.11 |
concurrency control - schedule과 serializability (0) | 2023.12.03 |
데이터베이스 Transaction 트랜잭션 / ACID (0) | 2023.12.03 |
SQL trigger (1) | 2023.12.03 |