동시성 문제, 격리
동시성 문제
같은 데이터에 동시 접근
웹처럼, 특정 값이 2가 있을 때 1로 바꾸기 위해 -1 했는데 2명이 동시에 하여, 0이 되버리는 상황
경쟁 상태 (Race Condition)
여러 클라이언트가 같은 데이터에 접근할 때 문제 발생
해결 방법
transaction isolation (격리)
서로 격리해서 다른 트랜잭션이 영향을 주지 못하게 함
쉬운방법
순서대로 실행하여 동시 접근 문제 자체가 없음. 하지만 너무 느림
다양한 격리 수준 지원
- Read Uncommitted (거의 사용 안함)
- Read Committed
- Repeatable Read
- Serializable
Read Committed
- dirty read, dirty write를 해결
- 커밋된 데이터만 읽기 -> 커밋된 값과 트랜잭션 진행 중인 값을 따로 보관
- 커밋된 데이터만 덮어쓰기 -> 행 단위 잠금 사용 -> 같은 데이터를 수정한 트랜잭션이 끝날 때까지 대기
Repeatable Read
- read skew 해결
- Transaction 동안 같은 데이터를 읽게 함
- 구현 예: MVCC(Multi-version Concurrency Control)
- 읽는 시점에 특정 버전에 해당하는 데이터만 읽음
Serializable
- 인덱스 잠금이나 조건 기반 잠금 등 사용
- 읽는 동안 데이터 변경 2 해결
동시성 관련 다양한 문제들
- 커밋되지 않은 데이터 읽기
- 커밋되지 않은 데이터 덮어쓰기
- 읽는 동안 데이터 변경 1st
- 변경 유실
- 읽는 동안 데이터 변경 2nd
커밋되지 않은 데이터 읽기 (dirty read)
커밋되지 않은 데이터 덮어쓰기 (dirty write)
읽는 동안 데이터 변경 (read skew)
- 읽는 시점에 따라 데이터가 바뀜
- 윗 사람 입장에서는 A의 값이 이상해짐
읽는 동안 데이터 변경 2 (read skew)
- 한 트랜잭션의 결과가 다른 트랜잭션의 쿼리 결과에 영향
- 같은 데이터를 쓰지 않지만 실제로는 경쟁 상태
변경 유실 (Lost Update)
- 같은 데이터를 쓸 때 발생
- 예) count 증가, 위키 페이지 수정
- 기대하는건 readcnt 가 3이여야 하는데 2로 변경됨
변경 유실에 대한 처리 방법
원자적 연산
- DB가 지원하는 원자적 연산 사용 > 동시 수정 요청에 대해 DB가 순차 처리
- DB 지원 여부 확인
명시적 잠금
- 조회 할 때 수정할 행을 미리 잠금
- 예) select .. for update
CAS (Compare And png)
- 수정할 때 값이 같은지 비교
Reference
아래의 URL를 정리한 글입니다.
https://www.youtube.com/watch?v=JJJ4LReZ5q4