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 |