본문 바로가기

cs(with 매일메일)

[250924수] 트랜잭션 격리수준은 무엇인가요?

트랜잭션 격리수준 : 동시에 여러 트랜잭션이 실행될 때, 트랜잭션이 다른 트랜잭션의 연산에 영향을 받지 않도록 하는 정도로, 개발자가 트랜잭션 격리 수준을 설정할 수 있는 기능을 제공한다.

 

낮은 격리 수준 : 동시 처리 능력 향상, 데이터 일관성 문제

높은 격리 수준 : 데이터 일관성 보장, 동시 처리 능력 떨어짐

> 즉, 데이터의 정합성과 성능이 반비례하다. 

 

 

격리 수준

READ UNCOMMITTED : 커밋되지 않은 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 조회하는 것을 허용

 

READ COMMITTED : 커밋된 데이터만 읽기

- Oracle, PostgreSQL

- 성능과 안정성의 균형

- 동시성이 놓음

- Dirty-Read 방지

 

- 반복 읽기 시, 값이 달라질 수 있음

- 팬텀 리드 발생 가능성 있음

 

REPEATABLE READ : 한 트랜잭션에서 특정 레코드를 조회할 때, 항상 같은 데이터를 응답하는 것을 보장

- MySQL

- 트랜잭션 내에서는 항상 같은 결과 반환

- 더 높은 일관성 제공

- MySQL에서는 팬텀 리드도 거의 방지

- 금융, 예약 시스템에 적합

 

- 잠금이 더 많이 발생하기에, 데드락 가능성 증가함.

 

SERIALIZABLE : 특정 트랜잭션이 사용중인 테이블의 모든 행을 다른 트랜잭션이 접근할 수 없도록 잠금

- 가장 엄격한 격리 수준

- 이름 그대로 트랜잭션을 순차적으로 진행

- 순수한 SELECT 작업에서도 넥스트 키 락을 공유락으로 걸기 때문에, 레코트 + 범위 전체를 공유락으로 걸어 가장 안전하지만 성능이 떨어진다. 

 

 

트랜잭션 격리 수준에 따른 발생 가능문제점

1. Dirty Read : 커밋되지 않은 데이터를 읽는 문제

2. Non-Repeatable Read : 같은 데이터를 다시 읽었는데 값이 변경된 문제

3. Phantom Read : 같은 조건으로 조회했는데 레코드 개수가 달라지는 문제

  READ UNCOMMITTED READ COMMITTED REPEATABLE READ SERIALIZABLE
Dirty Read
Phantom Read ⭕ (MySQL 거의없음)
Non-Repeatable Read

 

 

 

 

!! 추가 공부할 사항,,(아직은 너무 어렵다)

참고) [MySQL] 트랜잭션의 격리 수준(Isolation Level)에 대해 쉽고 완벽하게 이해하기 - MangKyu's Diary

 

 

 

===

✨데이터베이스의 락(Lock) 종류

1) 공유락( Shared Lock , 읽기 잠금) : 여러 트랜잭션이 동시 읽기는 가능, 누군가 읽는 동안 수정/삭제는 불가능

2) 베타락( Exclusive Lock , 쓰기 잠금) : 읽기,수정 모두 불가능 (하나의 트랜잭션이 완전히 독점적으로 사용)

 

✨SELECT문의 종료

1) 순수한 SELECT( SELECT * FROM users WHERE id = 1; )

    - 아무런 잠금 없이 데이터를 읽는다. 

    - 다른 트랜잭션이 수정중이어도 과거 시점의 데이터(스냅샷)을 읽음

시간 0: 계좌 잔액 = 1000원
시간 1: A가 SELECT (1000원 읽음)
시간 2: B가 UPDATE로 500원 출금 (잔액 = 500원)
시간 3: A가 다시 SELECT (여전히 1000원 읽음 - 과거 스냅샷)

 

2) SELECT FOR SHARE(공유락) ( SELECT * FROM users WHERE id = 1 FOR SHARE; )

    - 읽으면서 공유락을 건다. 

    - 다른 사람도 FOR SHARE로 읽을 수는 있음. 

    - 하지만 누군가 UPDATE/DELETE 하려면 대기해야 함

 

3) SELECT FOR UPDATE(베타락) ( SELECT * FROM users WHERE id = 1 FOR UPDATE; )

    - 다른 트랜잭션은 읽기도 수정도 불가능 (대기해야 함)

 

✨넥스트 키 락

- 레코드 그 자체 + 그 앞의 범위까지 함께 잠그는 방식

- 팬텀 리드 문제를 방지하기 위해 등장

    ?? 팬텀 리드란(Phantom유령): 같은 조건으로 조회했는데, 이전에 없던 데이터가 갑자기 나타나거나 사라지는 현상

- 중간에 다른 트랜잭션 실행으로 인해, 유령 데이터 생성을 막기 위해, 범위 자체를 잠그는 것. 

 

✨데드락

- 두 개 이상의 트랜잭션이 서로가 가진 자원을 기다리면서 영원히 대기하는 상태 

- 발생 조건 4가지

    1) 상호 배제 : 하나의 자원은 한 번에 하나의 트랜잭션만 사용할 수 있다

    2) 점유와 대기 : 자원을 가진 상태로 다른 자원을 기다린다

    3) 비선점 : 다른 트랜잭션의 자원을 강제로 빼앗을 수 없다

    4) 순환 대기 :  대기 관계가 원(circle)을 이룬다

- 해결방법(추천) : 자원 접근 순서를 통일하여 순환 대기를 해결한다! 

  > 모든 트랜잭션이 자원을 항상 같은 순서로 접근하게 만든다. 

구현 방법:
1. ID 기준으로 정렬
2. 작은 것부터 큰 것 순서로 접근
3. 모든 트랜잭션에 일관되게 적용