CHHB stroy

[DB] 트랜잭션 완전 정리 본문

DB

[DB] 트랜잭션 완전 정리

CHHB 2025. 9. 23. 11:40

1. 트랜잭션(Transaction)이란?

트랜잭션은 데이터베이스에서 하나의 논리적 작업 단위로, 여러 개의 데이터베이스 연산들을 묶어서 모두 성공하거나 모두 실패하도록 하는 메커니즘입니다.

핵심 개념

  • All or Nothing: 전부 성공하거나 전부 실패
  • 논리적 작업 단위: 업무상 나누어질 수 없는 최소 단위
  • 데이터 일관성 보장: 데이터베이스의 무결성 유지

2. 트랜잭션의 ACID 속성 ⭐⭐⭐

ADsP 시험에서 가장 중요한 개념입니다!

2.1 원자성(Atomicity)

정의: 트랜잭션의 모든 연산이 완전히 수행되거나 전혀 수행되지 않아야 함

특징:

  • All or Nothing 원칙
  • 중간 상태는 존재하지 않음
  • 실패 시 모든 변경사항 취소(Rollback)

예시:

-- 계좌 이체 트랜잭션
BEGIN TRANSACTION;
    UPDATE Account SET balance = balance - 100000 WHERE account_no = 'A001'; -- 출금
    UPDATE Account SET balance = balance + 100000 WHERE account_no = 'B001'; -- 입금
COMMIT; -- 둘 다 성공해야 커밋

-- 만약 입금 과정에서 오류 발생 시
-- 출금도 함께 취소되어 원래 상태로 복구

2.2 일관성(Consistency)

정의: 트랜잭션 실행 전후에 데이터베이스가 일관된 상태를 유지해야 함

특징:

  • 무결성 제약조건 위배 금지
  • 비즈니스 규칙 준수
  • 데이터베이스의 논리적 정확성 보장

예시:

-- 일관성 위배 예시 (이런 상황이 발생하면 안됨)
-- 총 잔액: A계좌(50만) + B계좌(30만) = 80만

BEGIN TRANSACTION;
    UPDATE Account SET balance = balance - 100000 WHERE account_no = 'A001'; -- 출금 성공
    -- 여기서 시스템 오류로 입금 실패
    UPDATE Account SET balance = balance + 100000 WHERE account_no = 'B001'; -- 입금 실패
-- 결과: A계좌(40만) + B계좌(30만) = 70만 ❌ (10만원 증발)

-- 일관성 보장: 트랜잭션 실패 시 A계좌도 원상복구되어 총액 80만 유지 ✅

2.3 독립성/격리성(Isolation)

정의: 동시에 실행되는 트랜잭션들이 서로 영향을 주지 않아야

특징:

  • 동시성 제어 필요
  • 각 트랜잭션은 독립적으로 실행되는 것처럼 보임
  • Lock 메커니즘 사용

예시:

-- 트랜잭션 T1 (사용자 A)
BEGIN TRANSACTION;
    SELECT balance FROM Account WHERE account_no = 'C001'; -- 잔액: 100만
    UPDATE Account SET balance = balance - 50000 WHERE account_no = 'C001';
COMMIT;

-- 트랜잭션 T2 (사용자 B) - 동시 실행
BEGIN TRANSACTION;
    SELECT balance FROM Account WHERE account_no = 'C001'; -- 잔액: 100만 (T1 영향 받지 않음)
    UPDATE Account SET balance = balance + 30000 WHERE account_no = 'C001';
COMMIT;

-- 격리성이 보장되지 않으면 Lost Update 문제 발생 가능

2.4 지속성(Durability)

정의: 성공적으로 완료된 트랜잭션의 결과는 영구적으로 보존되어야 함

특징:

  • 시스템 장애 발생해도 결과 유지
  • 로그 파일, 백업 등으로 보장
  • 물리적 저장소에 반영

예시:

-- 트랜잭션 완료 후
COMMIT; -- 이 시점에서 결과가 디스크에 영구 저장

-- 이후 시스템이 갑자기 다운되어도
-- 커밋된 트랜잭션의 결과는 유지됨
-- 시스템 재시작 후에도 데이터 그대로 존재

3. 트랜잭션의 상태(Transaction State)

3.1 5가지 상태

[Active] → [Partially Committed] → [Committed]
   ↓              ↓
[Failed] ←  [Aborted]

1. Active (활동 상태)

  • 트랜잭션이 실행 중인 상태
  • 아직 완료되지 않음

2. Partially Committed (부분 완료 상태)

  • 마지막 연산까지 실행 완료
  • 아직 디스크에 저장되지 않은 상태

3. Committed (완료 상태)

  • 트랜잭션이 성공적으로 완료된 상태
  • 모든 변경사항이 영구적으로 저장

4. Failed (실패 상태)

  • 트랜잭션 실행 중 오류 발생
  • 더 이상 진행할 수 없는 상태

5. Aborted (철회 상태)

  • 트랜잭션이 취소되어 원래 상태로 복구
  • Rollback 완료된 상태

4. 트랜잭션 동시성 제어

4.1 동시성 제어가 필요한 이유

여러 사용자가 동시에 같은 데이터에 접근할 때 발생하는 문제들:

1) Lost Update (갱신 손실)

-- 시간 순서
T1: READ(A=100)
T2: READ(A=100)
T1: A = A - 50 (A=50)
T2: A = A + 30 (A=130) -- T1의 변경사항 손실!
T1: WRITE(A=50)
T2: WRITE(A=130)
-- 결과: A=130 (T1의 -50 변경사항 손실)

2) Dirty Read (오손 데이터 읽기)

-- T1이 커밋하기 전 데이터를 T2가 읽는 경우
T1: UPDATE Account SET balance = 50000 WHERE id = 'A001'; -- 아직 커밋 안됨
T2: SELECT balance FROM Account WHERE id = 'A001'; -- 50000 읽음 (Dirty Read)
T1: ROLLBACK; -- T1 실패로 원복
-- T2는 잘못된 데이터(50000)를 읽었음

3) Non-Repeatable Read (반복 불가능 읽기)

-- 같은 트랜잭션에서 같은 데이터를 두 번 읽었는데 값이 다른 경우
T1: SELECT balance FROM Account WHERE id = 'A001'; -- 100000 읽음
T2: UPDATE Account SET balance = 50000 WHERE id = 'A001';
T2: COMMIT;
T1: SELECT balance FROM Account WHERE id = 'A001'; -- 50000 읽음 (값이 달라짐)

4) Phantom Read (환상 읽기)

-- 같은 조건으로 검색했는데 결과 집합이 달라지는 경우
T1: SELECT * FROM Account WHERE balance > 100000; -- 3건 조회
T2: INSERT INTO Account VALUES('NEW', 150000);
T2: COMMIT;
T1: SELECT * FROM Account WHERE balance > 100000; -- 4건 조회 (Phantom 발생)

4.2 격리 수준(Isolation Level)

격리 수준이 높을수록 데이터 일관성 ↑, 동시성 ↓

격리수준 Dirty Read Non-Repeatable Read Phantom Read 동시성
Read Uncommitted 발생 발생 발생 높음
Read Committed 방지 발생 발생
Repeatable Read 방지 방지 발생
Serializable 방지 방지 방지 낮음

Read Uncommitted

  • 가장 낮은 격리 수준
  • 커밋되지 않은 데이터도 읽기 가능
  • 모든 동시성 문제 발생 가능

Read Committed (기본값)

  • 커밋된 데이터만 읽기 가능
  • Dirty Read 방지
  • 대부분의 DBMS 기본 설정

Repeatable Read

  • 같은 트랜잭션 내에서 일관된 읽기 보장
  • Non-Repeatable Read 방지
  • MySQL InnoDB 기본 설정

Serializable

  • 가장 높은 격리 수준
  • 모든 동시성 문제 방지
  • 성능이 가장 낮음

5. Lock 메커니즘

5.1 Lock의 종류

1) Shared Lock (S-Lock, 공유 잠금)

  • 읽기 작업에 사용
  • 여러 트랜잭션이 동시에 S-Lock 획득 가능
  • S-Lock이 걸린 데이터는 읽기만 가능, 쓰기 불가

2) Exclusive Lock (X-Lock, 배타적 잠금)

  • 쓰기 작업에 사용
  • 하나의 트랜잭션만 X-Lock 획득 가능
  • X-Lock이 걸린 데이터는 다른 트랜잭션의 접근 불가

5.2 Lock 호환성 매트릭스

S-Lock X-Lock
S-Lock ✅ 호환 ❌ 비호환
X-Lock ❌ 비호환 ❌ 비호환

5.3 2단계 잠금 프로토콜(2PL)

Growing Phase (확장 단계)

  • Lock만 획득 가능
  • Lock 해제 불가

Shrinking Phase (축소 단계)

  • Lock만 해제 가능
  • Lock 획득 불가
-- 2단계 잠금 프로토콜 예시
BEGIN TRANSACTION;
-- Growing Phase
LOCK A (S-Lock);  -- Lock 획득
LOCK B (X-Lock);  -- Lock 획득
... 작업 수행 ...
-- Shrinking Phase  
UNLOCK A;  -- Lock 해제
UNLOCK B;  -- Lock 해제
COMMIT;

6. 데드락(Deadlock)

6.1 데드락이란?

두 개 이상의 트랜잭션이 서로의 Lock을 기다리며 영원히 대기하는 상황

6.2 데드락 발생 예시

-- 트랜잭션 T1
BEGIN TRANSACTION;
LOCK A (X-Lock);  -- A를 잠금
... 
LOCK B (X-Lock);  -- B 잠금 대기 (T2가 B를 잠그고 있음)

-- 트랜잭션 T2  
BEGIN TRANSACTION;
LOCK B (X-Lock);  -- B를 잠금
...
LOCK A (X-Lock);  -- A 잠금 대기 (T1이 A를 잠그고 있음)

-- T1은 T2를 기다리고, T2는 T1을 기다림 → 데드락 발생!

6.3 데드락 해결 방법

1) 예방(Prevention)

  • 순서대로 Lock 획득: 모든 트랜잭션이 같은 순서로 자원 요청
  • 타임스탬프 기반: 트랜잭션 시작 시간에 따라 우선순위 부여

2) 탐지 및 회복(Detection & Recovery)

  • Wait-for Graph로 데드락 탐지
  • 탐지 시 희생자(Victim) 선정하여 Rollback

3) 회피(Avoidance)

  • 타임아웃 설정: 일정 시간 대기 후 자동 철회

7. 회복(Recovery) 기법

7.1 로그 기반 회복

UNDO 연산

  • 실패한 트랜잭션의 변경사항을 원래 상태로 복구
  • Before Image(변경 전 값) 사용

REDO 연산

  • 성공한 트랜잭션의 변경사항을 다시 적용
  • After Image(변경 후 값) 사용

7.2 체크포인트(Checkpoint)

  • 주기적으로 현재 상태를 저장
  • 시스템 장애 시 체크포인트 이후부터만 회복 수행
  • 회복 시간 단축

7.3 회복 과정

시스템 장애 발생
↓
가장 최근 체크포인트 찾기
↓  
체크포인트 이후 완료된 트랜잭션: REDO
↓
체크포인트 이후 미완료 트랜잭션: UNDO
↓
회복 완료