Notice
Recent Posts
Recent Comments
Link
CHHB stroy
[DB] 트랜잭션 완전 정리 본문
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
↓
회복 완료'DB' 카테고리의 다른 글
| MSSQL 인덱스의 INCLUDE, 이거 모르면 인덱스를 반만 쓰는 거다 (0) | 2026.05.19 |
|---|---|
| PostgreSQL, 왜 다들 Postgres 쓰라고 하는지 이제 알겠다 (0) | 2026.05.12 |
| SQL Server PIVOT과 UNPIVOT 완벽 정리 (0) | 2026.05.11 |
| [DB] 데이터베이스 키(KEY) 종류 정리 (0) | 2025.09.23 |