[DB] Transaction

춤추는 머쉬룸·2024년 4월 22일
0

2024 CNU NHN ACADEMY

목록 보기
11/15

ACID - DB의 4대 속성

사실 Transaction 의 4대 속성

A : Atomicity (원자성) - 절대로 쪼개지면 안됨. 쪼개질 수 없다.

C : Consistency (일관성) - 실행을 완료하면 모든 데이터가 모두 기록되어야 함.

I : Isolation (격리성) - 트랜젝션 실행 중에는 다른 트랜젝션이 개입하지 못함.

D : Durability (지속성) - 트랜젝션에 성공했으면 영구적으로 dB 에 반영되어야 함.

병행성 제어

동시에 두 개의 프로세스가 한 데이터에 접근하려고 하면 오류남. 그걸 해결하려면,

프로세스 : (Race condition) → (상호 배제) → (critical section) → (세마포어, 뮤텍스)

그런데, 트랜잭션에서는?

여러 개의 데이터에 관련이 되어있으면, 하나가 실패하면 모두다 실패한 것임.

하나라도 실패하면 roll back 해야 함.

잠금하고, 작업이 느려지면, 모든 시스템이 다 느려짐. 기다려야 하기 때문.

단순하게 읽기만 할건데, 잠겨있으면? 기다리다 죽음.

잠금의 종류

Exclusive Lock : 내가 쓰는 중에는 읽기, 쓰기, 수정 다 불가능

  • 퍼포먼스 측면에서는 성능 저하

Shared Lock : 내가 쓰는 중에 읽기 가능

  • 읽을 때 다르게 읽힐 수 있음

Isolation Level

  • Read Uncommited : Commit 되지 않은 데이터(Dirty read 한 데이터)를 읽겠다. - 무결성은 무시하고 성능 위주 -> Dirty, Phantom, Repeatable 모두 발생
  • Read Commited : Commit 된 데이터만 읽겠다. -> Phantom, Repetable 만 발생
  • REPEATABLE READ : Page lock 관련
  • Serializable : 읽기와 쓰기 관련된 건 다 잠금 (index lock)

오라클이 트랜잭션 관리를 잘 함. 그래서 널리 쓰임

Transaction 문제 발생

  • Dirty read : 트랜잭션 상태에 따라 일관성이 무너짐
  • Phantom read :
  • Repeatable read : 반복값을 update 하는 경우

분산 트랜잭션

서로 다른 DB에서 모두 다 끝나면 끝난걸로 확인

IBM : CORBA, MS : COMT


DB에 일을 시키면?

  1. Query Optimizer : 쿼리를 대충 짜도 알아서 효율적으로 바꿔줌
  2. Buffer Manager : Buffer pool 를 만듦
    1. Dirty bit : 데이터가 메모리에 와서 변경되었는 지 아닌지 기록
    2. Pin :
    3. Slot : 데이터가 꽂힘
    4. 가변 길이, 고정 길이
    5. RID : 페이지 번호 + 레코드 번호
  3. Disk : 실제 데이터가 있음
    1. 페이징을 해서 Buffer manager 에 올림
    2. 페이지가 올라와서 프레임에 꽂힌 형식
  4. 페이지 안에는 Record 라고 함

뭘 잠글까…?

메모리에서 잠근다!

메모리에는 페이지와 레코드가 있다

잠금의 깊이

X Lock : 나만 보겠다. 아무도 읽지도 말고 쓰지도 마

S Lock : 나는 쓸 수 있는데 다른 사람은 읽기만 가능

잠금의 종류 - DB 마다 다름

R 레코드 잠금 : 하나의 투플을 잠그는 것

  • 어떤 사람에 대해 잠금을 걸 때.

P 페이지 전체 잠금 :

  • where id=1; 이면 페이지에 건다.

I 인덱스 잠금

T 테이블 잠금

mysql 은 X,S,R,P,I 만 있음


트랜잭션과 일관성

자바에서는 모든 트랜잭션이 순서대로 실행된 결과를 보장하기 위해 메소드에 Syncronized 키워드를 붙임. 그래서 모든 트랜젝션이 나열(Serialize)이 되도록 동기화 함 → Thread safe 함. 병행성 제어면에서는 좋은데, 성능이 떨어짐.

Vector : 배열로 만들어진 List. (Array list 와 같음). thread safe 하게 만들어짐.

그런데, 너무 느려서 Syncronized 를 빼고 array list 로 바꿈.


Lock Mode

  • 직렬성을 보장하기 위한 방법으로, 데이터 객체들이 상호 배타적으로 액세스 되도록 함
  • 한 트랜잭션이 한 데이터 객체에 액세스 했을 때 다른 트랜잭션이 해당 객체를 수정하지 못하도록 함
  • 다중 트랜잭션 환경에서 데이터베이스의 일관성과 무결성을 유지하기 위한 순차적 진행을 보장
  • 잠금 모드
    • Shared Lock Mode(Read Lock)
      • 트랜잭션 Ti 가 데이터 객체 A에 Shared Lock을 가지고 있다면 Ti 는 A를 읽을 수 있지만 갱신할 수 없음
      • SELECT
    • Exclusive Lock Mode(Write Lock – X로 표시)
      • 트랜잭션 Ti 가 데이터 객체 A에 Exclusive Lock을 가지고 있다면 Ti 는 A를 읽을 수도, 갱신할 수도 없음
      • UPDATE, DELETE, INSERT

Strict 2 Phase Lock

가장 널리 사용되는 잠금 규약으로, 두 가지 규칙을 사용
DB 에서 Transaction 에 대한 잠금 규약

  • 트랜잭션 T가 어떤 객체를 판독(수정)하려면, 그 객체에 대해 공유(배타적) 잠금을 요청

  • 트랜잭션이 종료될 때 가지고 있던 모든 잠금을 풀어줌

잠금 규약은 안전한 인터리빙만을 어용함

두 트랜잭션이 동일한 객체에 접근하며, 한 트랜잭션이 객체를 수정하려 할 때, 단위 작업이 직렬 순서로 수행한 효과를 얻도록 함

DB 의 DeadLock (교착 상태)

  • 두 트랜잭션이 잠금 해제를 기다리는 관계에 사이클이 생기는 경우

T1이 A를 막고, T2가 B를 막았는데, T1이 B 를 접근하려고 하고, T2 를 A가 접근하려고 한다.

해결방법
트랜잭션마다 우선순위를 부여해주고 우선 순위가 낮은 트랜잭션은 우선순위가 높은 트랜잭션을 기다릴 수 없도록 하여 예방

진짜로 뭘 잠글까..?

Dirty Read : Record 잠금
Phantom Read : Index 잠금
Repeatable Read : Page 잠금

0개의 댓글