STUDY

SECTION 4.3 트랜잭션과 무결성

Lim임 2026. 3. 10. 13:34

SECTION 4.3 트랜잭션과 무결성

4.3.1 트랜잭션 (Transaction)

하나의 논리적 기능을 수행하기 위한 *여러 쿼리들을 하나로 묶은 작업 단위
*이에 대한 특징은 원자성, 일관성, 독립성, 지속성이 있으며 이를 ACID특징이라고 함.

커밋 & 롤백

  • 커밋(commit): 여러 쿼리가 성공적으로 처리되어 DB에 영구 저장 확정
  • 커밋이 수행되었다 = 하나의 트랜잭션이 성공적으로 수행되었다.

  • 롤백(rollback): 문제 발생 시 트랜잭션 이전 상태로 취소/복원
  • 커밋·롤백 덕분에 데이터 무결성 보장

트랜잭션 전파

트랜잭션을 수행할 때 커넥션 단위로 수행하기 때문에 커넥션 객체를 넘겨야 함 -> 매번 하기 어렵고 귀찮음

커넥션 객체를 매번 넘기지 않고, 여러 메서드를 하나의 트랜잭션으로 묶는

ACID 특징

A — 원자성 (Atomicity) : "All or Nothing"

트랜잭션 내의 모든 작업은 전부 성공하거나 전부 실패해야 합니다.

[이체 예시]
1. 홍철 잔고 조회 (1000만원)
2. 홍철 잔고에서 500만원 차감
3. 규영 잔고에 500만원 추가

→ 2번에서 오류 발생 시? 1, 2번 모두 롤백 → 처음 상태로 완전 복구
→ 홍철 500만원 / 규영 0원 같은 "중간 상태"는 절대 허용 안 됨
  • 커밋: 모두 성공 → 영구 저장
  • 롤백: 하나라도 실패 → 전체 취소
  • 트랜잭션 내에 외부 API 호출이 있다면, 롤백 시 처리 방법을 반드시 고려해야 함

C — 일관성 (Consistency) : "규칙을 항상 준수"

트랜잭션이 완료된 후에도 데이터베이스는 미리 정의된 규칙·제약 조건을 항상 만족해야 합니다.

[예시]
범석 잔고: 0원
범석이 500만원 이체 시도 → ❌ 불가

0원에서 500만원이 나오는 것은 "잔고 >= 0" 규칙 위반
→ DB가 이 트랜잭션을 거부하여 일관성 유지
  • 트랜잭션 실행 전후 모두 유효한 상태를 유지해야 함
  • 제약 조건(기본키, 외래키, 도메인 규칙 등)을 위반하는 데이터 변경은 허용되지 않음

I — 격리성 (Isolation) : "트랜잭션끼리 서로 간섭 금지"

여러 트랜잭션이 동시에 실행될 때, 각 트랜잭션은 다른 트랜잭션의 중간 상태를 볼 수 없어야 합니다.

[예시]
사용자 A: 잔고 조회 중 (트랜잭션 진행 중)
사용자 B: 동시에 같은 잔고를 수정 중

→ A는 B가 수정 중인 "확정되지 않은" 값을 보면 안 됨
→ 마치 순차적으로 실행된 것처럼 동작해야 함
  • 격리 수준(SERIALIZABLE, REPEATABLE_READ, READ_COMMITTED, READ_UNCOMMITTED)으로 강도 조절 가능
  • 격리성이 강할수록 동시성(성능)은 낮아짐

D — 지속성 (Durability) : "한 번 커밋되면 영구 보존"

성공적으로 커밋된 트랜잭션은 시스템 장애(정전, 오류)가 발생해도 반드시 유지되어야 합니다.

[예시]
이체 완료 후 커밋 → 서버 갑자기 다운
→ 재시작 후에도 이체된 내용은 그대로 유지되어야 함
  • 체크섬: 데이터 무결성 오류 검출
  • 저널링: 변경 전 로그를 먼저 기록해 복구 가능하게 함
  • 롤백: 장애 시 마지막 커밋 상태로 복구

🔒 격리성 — 격리 수준

위로 갈수록 동시성 ↑, 격리성 ↓ / 아래로 갈수록 동시성 ↓, 격리성 ↑

낮은 격리 (빠름)  READ_UNCOMMITTED
                  READ_COMMITTED
                  REPEATABLE_READ
높은 격리 (느림)  SERIALIZABLE

1. READ_UNCOMMITTED (가장 낮은 격리)

커밋되지 않은 데이터도 읽을 수 있는 수준.

  • 발생 현상: 더티 리드, 반복 불가 조회, 팬텀 리드 모두 발생 가능
  • 데이터 무결성에 위험하므로 되도록 사용하지 않는 것이 좋음
  • 단, 거대한 데이터를 "어림잡아" 집계할 때는 유용할 수 있음
[더티 리드 예시]
사용자 A: 보석 개수 100 → 1로 수정 (아직 커밋 안 함)
사용자 B: 조회 → 1로 읽음 ← 커밋 안 된 값을 읽어버림
사용자 A: 롤백 → 실제 값은 100이지만 B는 이미 1을 읽은 상태

2. READ_COMMITTED

커밋이 완료된 데이터만 읽을 수 있는 수준.

  • 발생 현상: 반복 불가 조회, 팬텀 리드 발생 가능
  • 가장 많이 사용되는 격리 수준
  • 기본값: PostgreSQL, SQL Server, Oracle
  • 커밋되지 않은 정보는 읽을 수 없지만, 다른 트랜잭션이 접근한 행을 수정할 수 있음
[반복 불가 조회 예시]
사용자 A: 보석 100 조회
사용자 B: 보석 100 → 1로 수정 후 커밋
사용자 A: 다시 조회 → 1로 읽힘 (같은 트랜잭션인데 값이 달라짐)

3. REPEATABLE_READ

한 트랜잭션 내에서 같은 행을 읽으면 항상 같은 값을 보장하는 수준.

  • 발생 현상: 팬텀 리드 발생 가능
  • 기본값: MySQL InnoDB
  • 수정(UPDATE)은 막지만, 삽입(INSERT)/삭제(DELETE)는 막지 않음
[팬텀 리드 예시]
사용자 A: age >= 12인 회원 조회 → 3건
사용자 B: age = 15인 회원 삽입 후 커밋
사용자 A: 다시 조회 → 4건 (행이 추가되어 결과가 달라짐)

4. SERIALIZABLE (가장 높은 격리)

트랜잭션을 순차적으로 처리하는 수준.

  • 발생 현상: 없음 (가장 안전)
  • 여러 트랜잭션이 동시에 같은 행에 접근 불가
  • 교착 상태 발생 가능성이 높고 성능이 가장 낮음
트랜잭션 A가 행 X를 처리 중
  → 트랜잭션 B가 행 X 접근 시도
    → B는 A가 끝날 때까지 대기

발생 현상 상세

더티 리드 (Dirty Read)
  • 한 트랜잭션이 커밋되지 않은 다른 트랜잭션의 데이터를 읽는 현상
  • 롤백 시 실제로 존재하지 않는 값을 읽은 것이 됨
반복 불가 조회 (Non-repeatable Read)
  • 한 트랜잭션 내에서 같은 행을 두 번 읽었을 때 값이 달라지는 현상
  • 다른 트랜잭션이 그 행을 수정(UPDATE) 하고 커밋했기 때문
팬텀 리드 (Phantom Read)
  • 한 트랜잭션 내에서 같은 쿼리를 두 번 실행했을 때 행 수가 달라지는 현상
  • 다른 트랜잭션이 행을 삽입(INSERT) 또는 삭제(DELETE) 했기 때문
  • 반복 불가 조회와의 차이: 행의 값이 바뀌는 게 아니라 행 자체가 추가/삭제됨
현상 원인 영향 범위
더티 리드 미커밋 데이터 읽기 행의 미확정 값
반복 불가 조회 타 트랜잭션 UPDATE 행의 값 변경
팬텀 리드 타 트랜잭션 INSERT/DELETE 결과 행 수 변경

4.3.2 무결성 (Integrity)

데이터의 정확성·일관성·유효성을 유지하는 것

종류 설명
개체 무결성 기본키는 빈 값(NULL) 허용 안 함
참조 무결성 참조 관계의 두 테이블 데이터는 항상 일관성 유지
고유 무결성 특정 속성은 고유한 값만 가져야 함
NULL 무결성 NULL 불가 조건이 있는 속성은 NULL이 될 수 없음

'STUDY' 카테고리의 다른 글

SECTION 4.5 인덱스  (1) 2026.03.18
SECTION 4.4 데이터베이스의 종류  (0) 2026.03.18
SECTION 4.2 ERD와 정규화 과정  (0) 2026.03.10
코드 리팩토링 - 멘토님의 조언을 적용해보자  (0) 2026.02.12
데이터베이스  (0) 2026.02.09