til
til copied to clipboard
트랜잭션
https://www.youtube.com/watch?v=urpF7jwVNWs
트랜잭션
- 여러 읽기/쓰기를 논리적으로 하나로 묶는다
- 원자성 (Atomicity): All or Nothing
트랜잭션 범위는 커넥션 기준
- 여러 메소드를 하나의 트랜잭션으로 묶고싶다면, 하나의 커넥션을 사용해야 한다.
- 트랜잭션 전파 기능을 사용한다.
트랜잭션과 외부 연동
- 외부 연동이 섞여 있으면 롤백 처리에 주의
글로벌 트랜잭션
- 두개 이상의 자원(DB, 메시징큐 등)을 한 트랜잭션으로 처리
- 거의 사용하지 않음
https://www.youtube.com/watch?v=poyjLx-LOEU
경쟁 상태 (Race Condition)
- 여러 클라이언트가 같은 데이터에 접근
- 트랜잭션 격리 (Isolation)
- 트랜잭션을 서로 격리해서 다른 트랜잭션이 영향을 주지 못하게 함
동시성 문제
커밋되지 않은 데이터
- Dirty Read: 커밋되지 않은 데이터 읽기
- Dirty Write: 커밋되지 않은 데이터 덮어쓰기
- Read Committed 격리 레벨
- 커밋된 데이터만 읽기
- 커밋된 값과 트랜잭션 진행 중인 값을 따로 보관
- 커밋된 데이터만 덮어쓰기
- 행 단위 잠금 사용
- 같은 데이터를 수정한 트랜잭션이 끝날 때 까지 대기
- 커밋된 데이터만 읽기
읽는 동안 데이터 변경 1
- Read Skew: 읽는 시점에 따라 데이터가 바뀜
- Repeatable Read 격리 레벨
- 트린잭션 동안 같은 데이터를 읽게 함
- 구현: MVCC (Multi-Version Concurrency Control)
- 읽는 시점에 특정 버전에 해당하는 데이터만 읽어옴
변경 유실
- Lost Update: 같은 데이터를 쓸 때 발생 (카운트 증가, 위키 페이지 수정 등)
- Atomic 연산 사용
- DB가 지원하는 기능 사용
-
update article set readcnt = readcnt + 1 where id = 1
- 명시적 잠금
- 조회할 때 수정할 행을 미리 잠금
-
select ... for update
- CAS (Compare and Set)
- 수정할 때 값이 같은지 비교
-
update wikipage set ver2, ... where id = 1 and ver = 1
읽는 동안 데이터 변경 2
- 한 트랜잭션의 결과가 다른 트랜잭션의 쿼리 결과에 영향
- 같은 데이터를 쓰지 않지만 실제로는 경쟁 상태 (당직자 문제)
- Serializable 격리 레벨
- 인덱스 잠금이나 조건 기반 잠금 등 사용
정리
- 격리 수준을 이해하면 문제 발생을 줄일 수 있음
- 잠금 시간은 최소화
- 사용하는 DB의 기본 격리 레벨과 각각 격리 레벨의 동작 방식을 알아두면 좋다