MVCC 이전, dead lock과 트랜잭션 격리성
Dead lock
운영체제에서의 dead lock과 같은 맥락으로
DB 런타임에서 dead lock은
세션 a, b 중 하나가 뒤로 물러서지 않으면 리소스에 대한 lock이 풀리지 않는 상태를 말한다.
lock 구현은 벤더마다 구현이 다르다.
sql server에서는
- 갱신 update lock
- 의도 lock
- schema lock이 있다.
oracle에는
- 로우 lock
- table lock이 있다.
트랜잭션 격리성 수준
개인적으로 lock level이 더 잘 와닿음.
트랜잭션을 격리하기 위해
DB에서 취급하는 자료구조에 lock을 거는 범위가 계층화 되어있는데
이를 lock level이라고 함.
lock level
Row level : RID에만 lock
Page level : 변경하려는 page에 lock // page에 속한 row 모두 lock
Extent level :
Table level : table 전체와 관련 index에 lock
Lock escalation
관리할 lock 리소스가 정해진 임계치를 넘으면
row -> page -> extent -> table -> db 락으로 점점 확장한다.
상위 레벨의 lock이 걸린 경우
하나의 lock으로 수많은 레코드를가 한 꺼번에 잠긴다.
- lock level이 낮을수록 동시성이 좋음.
- lock level이 높을수록 동시성이 떨어짐.
- 관리해야할 lock 개수 증가하면, 리소스 증가
Trade Offs
트랜잭션 격리성을 높이기 위해서는 Lock을 오래 유지하면 된다.
그러나 Lock을 오래 유지하면 동시성이 떨어진다.
낮은 단계 격리성의 문제점
1. Dirty read : 비일관성. 커밋하지 않은 데이터를 읽는다.
2. Non-repeatable read : 다른 트랜잭션의 작업에 의해 read 결과가 다르게 나타남
3. Phantom read : 1번째 쿼리에 없던 record가 2번째 query에서 등장
트랜잭션 격리성을 유지하면서
동시성을 높이기 위해 다양한 방법들이 고안되었다.
ANSI 표준, 트랜잭션 격리성 레벨
낮은 등급부터
Read uncommitted
Read committed : dirty read 방지, non-repeatable read, phantom read 현상을 막진 못함.
Repeatable Read
Serializable Read : locking에 의존, share lock을 트랜잭션이 끝날 때까지 유지
모든 DBMS가 4가지 Level을 다 지원하지는 않음.
동시성 제어
비관적 동시성 제어
- 사용자들이 같은 data를 동시에 수정할 것이라고 가정.
- 읽는 시점에 lock 설정 o, 트랜잭션이 끝날 때까지 유지 ( hold lock )
- 동시성 저하에 대한 대안
wait ( 3초 대기 후 exception ), no wait( 대기없이 exception )
wait ( 3초 대기 후 exception ), no wait( 대기없이 exception )
낙관적 동시성 제어
- 사용자들이 같은 data를 동시에 수정하지 않을 것이라고 가정.
- 읽을 시점에 lock 설정 x, 수정 시점에 다른 사용자에 의해 값이 변경됐는지 검사.
( 트랜잭션 수행시 데이터의 version을 검사해서, 다른 사람에 의해 달라진 version이라면
optimistic lock exception을 발생시킨다. 이에 따라 해당 트랜잭션은 commit 될 수 없다.
구현에 따라 timestamp를 검사하기도 한다.)
( 트랜잭션 수행시 데이터의 version을 검사해서, 다른 사람에 의해 달라진 version이라면
optimistic lock exception을 발생시킨다. 이에 따라 해당 트랜잭션은 commit 될 수 없다.
구현에 따라 timestamp를 검사하기도 한다.)
- 트랜잭션간 충돌이 발생할 때 데드락을 발생시킬 수 있음.
데이터 격리성 수준을 '트랜잭션'이 아니라 '스냅샷' 수준으로 관리할 경우
최초 데이터 뿐 아니라 다양한 '버전'의 데이터가 존재함.
댓글
댓글 쓰기