250x250
Notice
Recent Posts
Recent Comments
Link
반응형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 리소스모니터링
- scanner
- Calendar
- date
- Properties
- CSS
- 스택
- union_find
- dfs
- GC로그수집
- javascript
- List
- priority_queue
- BFS
- html
- 힙덤프
- set
- Java
- JPA
- string
- NIO
- math
- sql
- deque
- map
- 스프링부트
- alter
- 큐
- spring boot
- Union-find
Archives
- Today
- Total
매일 조금씩
트랜잭션 격리 수준 (feat. 비관적 락, 낙관적 락, MVCC) 본문
728x90
반응형
트랜잭션 격리 수준이란?
데이터베이스에서 여러 트랜잭션이 동시에 실행될 때,
각각의 트랜잭션이 다른 트랜잭션으로부터 얼마나 독립적으로 동작할 수 있는지를 정의하는 기준이다.
이를 통해 동시성 문제(Concurrency Issues)를 제어하고 데이터의 일관성을 유지한다.
주요 동시성 문제
- Dirty Read (더티 리드)
다른 트랜잭션이 아직 커밋하지 않은 데이터를 읽는 현상.
업데이트, 삭제에 대해 발생하고, 행 락으로 방지할 수 있다. Read Commited 이상에선 방지된다. - Non-Repeatable Read (반복 불가능한 읽기)
한 트랜잭션 내에서 같은 데이터를 두 번 읽을 때 값이 다른 현상. (다른 트랜잭션이 데이터를 수정한 경우) - Phantom Read (팬텀 리드)
한 트랜잭션이 동일한 쿼리를 두 번 실행할 때,
다른 트랜잭션의 삽입/삭제로 인해 데이터가 유령(Phantom)처럼 있었는데 없었어요 하며
조회 결과의 레코드 수나 내용이 달라지는 현상.
트랜잭션 격리 수준 종류 (DB 별로 다름)
- Read Uncommitted (읽기 미완료 허용)
- 커밋되지 않은 데이터를 읽을 수 있음.
- 가장 낮은 격리 수준, 높은 동시성 제공.
- 문제점: Dirty Read, Non-Repeatable Read, Phantom Read 발생 가능.
- Read Committed (읽기 완료 허용)
- 커밋된 데이터만 읽을 수 있음.
- Dirty Read 방지.
- 문제점: Non-Repeatable Read, Phantom Read 발생 가능.
- Repeatable Read (반복 가능한 읽기)
- 트랜잭션 내에서 동일한 데이터를 반복적으로 읽을 때 항상 같은 결과를 보장.
- Dirty Read와 Non-Repeatable Read 방지.
- 문제점: Phantom Read 발생 가능. (MySQL에선 발생 안함. 아래에서 설명)
- Serializable (직렬화 가능)
- 가장 높은 격리 수준.
- 트랜잭션을 순차적으로 실행하는 것처럼 동작.
- Dirty Read, Non-Repeatable Read, Phantom Read 모두 방지.
- 단점: 성능 저하, 동시성 감소.
격리 수준 선택 기준
- 동시성이 중요한 경우: 낮은 수준(Read Uncommitted, Read Committed).
- 데이터 일관성이 중요한 경우: 높은 수준(Repeatable Read, Serializable).
트랜잭션 격리 수준 설정 (SQL 예시)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
DB별 기본 격리 수준
- MySQL: Repeatable Read.
- Oracle: Read Committed.
- PostgreSQL: Read Committed.
트랜잭션 격리 수준은 총 4단계일까?
=> DB 마다 다르다. 위에 설명한 격리 수준은 MySQL 기준이고, 4단계이다.
MySQL은 기본으로 Repeatable Read 인데, Phantom Read가 발생하지 않는다?
=> 그렇다. MySQL의 InnoDB 스토리지 엔진은 MVCC(Multi-Version Concurrency Control)를 사용하기 때문에, Repeatable Read 격리 수준에서도 Phantom Read가 발생하지 않는다.
MySQL에서 Phantom Read 방지 메커니즘
- MVCC
MySQL의 InnoDB는 MVCC를 통해 트랜잭션이 시작될 때 스냅샷(Snapshot)을 생성하고, 해당 트랜잭션 동안 동일한 스냅샷을 참조한다. 이를 통해 반복 가능한 읽기(Repeatable Read)를 보장한다. - Next-Key Locking
MySQL은 Repeatable Read에서 레코드 락(Record Lock)과 갭 락(Gap Lock)을 조합한 Next-Key Locking을 사용.- 레코드 락: 특정 행(row)을 잠금.
- 갭 락: 특정 행 주변의 인덱스 범위(gap)를 잠금.
MySQL의 InnoDB는 MVCC와 Next-Key Locking 덕분에 Repeatable Read에서도 Phantom Read를 방지한다.
따라서 MySQL의 Repeatable Read는 다른 DBMS의 Serializable과 비슷한 수준의 격리성을 제공한다!!
Next-Key Locking과 트랜잭션 ID(Transaction ID)의 쓰임과 관계는?
- Next-Key Locking :
Next-Key Locking은 동시성 제어와 데이터 무결성 보장을 위해 MySQL InnoDB가 사용하는 잠금 메커니즘.- 목적: 트랜잭션 간 충돌을 방지하고 Phantom Read를 막기 위해 인덱스의 특정 범위와 해당 데이터를 잠금.
- 작동 방식:
- 레코드 락 (Record Lock): 행 자체에 락을 설정.(SELECT ... FOR UPDATE와 같은 쿼리에서 사용)
- 갭 락 (Gap Lock): 행 사이의 "갭"에 락을 설정. (id = 10, 20 이 있으면 10부터 20까지 갭에 락이 걸려서 id = 15를 insert 하려고 해도 안됨)
- Next-Key Lock: 레코드 락 + 갭 락을 결합하여 사용.
- 트랜잭션 ID (Transaction ID) :
트랜잭션 ID는 각 트랜잭션을 고유하게 식별하는 ID로, InnoDB에서 MVCC를 구현하는 데 사용.- 목적: 트랜잭션 간 데이터의 일관성을 보장하고, 어떤 트랜잭션이 어떤 데이터를 읽거나 변경했는지를 추적.
- 작동 방식:
- 트랜잭션이 시작될 때마다 고유한 트랜잭션 ID가 할당된다.
- MVCC는 이 트랜잭션 ID를 사용해 데이터의 버전을 관리.
- 특정 트랜잭션이 볼 수 있는 데이터의 범위를 결정.
728x90
반응형