트랜잭션(Transaction)
데이터베이스의 상태를 변경하는 하나의 논리적 작업 단위입니다. 이 작업들은 모두 성공하거나 모두 실패하며, 오류 복구를 단순화하고 데이터의 일관성과 신뢰성을 보장합니다. 또한, 웹에서는 클라이언트와 서버가 데이터를 주고받는 일련의 과정을 의미하기도 합니다.
트랜잭션의 ACID 속성
| 속성 |
설명 |
| 원자성(Atomicity) |
트랜잭션 내의 모든 작업이 성공하거나 실패해야 합니다.
작업 묶음이 쪼개지지 않고 하나처럼 움직여야 한다는 원리. 실패하면 전체가 롤백되고, 성공하면 전체가 커밋됩니다. |
| 일관성(Consistency) |
트랜잭션이 수행되는 동안 데이터베이스의 일관성이 유지됩니다.
트랜잭션 전후로 데이터 규칙, 제약조건, 도메인 법칙이 깨지지 않는 것. 예: 재고가 음수가 되면 안 된다는 규칙 같은 것들.
|
| 고립성(Isolation) |
다른 트랜잭션의 영향을 받지 않고 독립적으로 실행됩니다.
동시에 여러 트랜잭션이 실행되더라도 서로 방해하지 않고 독립적으로 보이게 해야 한다는 원칙. 바로 여기서 격리 수준이 등장합니다. Isolation은 하나의 철학이고, Isolation Level은 그 철학을 얼마나 강하게 적용할지 정한 옵션입니다. |
| 지속성(Durability) |
성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영됩니다.
트랜잭션이 커밋되면 정전, 서버 고장, 시스템 재부팅 등에도 데이터는 살아남는다는 보장. 스토리지 단까지 안전히 기록되는 것을 의미합니다.
|
트랜잭션 격리 수준
| 격리 수준 |
Dirty Read |
Non-Repeatable Read |
Phantom Read |
특징 요약 |
| Read Uncommitted |
허용 |
허용 |
허용 |
거의 격리 없음. 읽기 성능 최우선 환경에서만 사용 |
| Read Committed |
방지 |
허용 |
허용 |
대부분의 DB 기본값. 커밋된 데이터만 읽는다 |
| Repeatable Read |
방지 |
방지 |
DB마다 다름 (MySQL은 방지) |
같은 행을 항상 동일하게 본다 |
| Serializable |
방지 |
방지 |
방지 |
완전한 직렬화. 가장 안전하지만 가장 비용 높음 |
트랜잭션 격리 수준별 예시
1) Read Uncommitted
마치 창고 문이 열려 있는데, 안에서 아직 포장 중인 상품을 미리 들여다보는 느낌.
✅ T2가 커밋하지 않은 값도 읽을 수 있음 (Dirty Read)
예시
- T2: 잔액을 100에서 0으로 변경 중(아직 커밋 안됨)
- T1: 잔액 조회 -> 0 으로 보임
- T2: 롤백
- T1: "어? 방금 0이었는데 왜 다시 100이지?"
혼란이 생기는 환경.
2) Read Committed
남이 박스를 닫고 테이핑 완료해야만 볼 수 있는 상태.
✅ Dirty Read 방지
❌ Non-Repeatable Read 발생
예시
- T1: 잔액 조회 -> 100
- T2: 잔액을 150으로 변경 후 커밋
- T1: 다시 잔액 조회 -> 150
- T1이 같은 트랜잭션 안에서 두 번 읽었는데 값이 바뀜
3) Repeatable Read
일단 문을 닫아 잠그면, 그 안의 물건은 내가 보는 동안 바뀌지 않는 느낌.
✅ Dirty Read 방지
✅ Non-Repeatable Read 방지
❌ Phantom Read 가능(DB 종류에 따라 다름)
예시(고전적인 버전)
- T1: “잔액이 100인 계좌 조회”
- T2: 그 계좌 수정 → 커밋
- T1: 같은 계좌 다시 조회 → 여전히 100으로 보인다 (스냅샷 유지)
하지만
T1이 “잔액이 100 이상인 모든 계좌 목록”을 읽을 때는:
- T1: 목록 읽기 → 5개
- T2: 새 계좌 추가 → 커밋
- T1: 목록 다시 읽기 → 6개 (행이 “훅” 나타남)
이 새롭게 나타난 행이 Phantom(유령) 현상.
참고: MySQL(InnoDB)
Repeatable Read에서 Gap Lock을 사용해 Phantom Read도 방지함.
4) Serializable
모든 트랜잭션을 “차례대로 줄 세워서” 처리하는 느낌.
✅ Dirty Read 방지
✅ Non-Repeatable Read 방지
✅ Phantom Read 방지
✅ 가장 안전
❌ 성능 부담 가장 큼 (대기시간 증가)
예시
- T1: “잔액 100 이상 계좌 목록 조회 시작”
- T2: 새로운 계좌 추가 시도 → T1이 끝날 때까지 대기
- T1이 끝난 뒤에야 T2가 실행됨
DB가 트랜잭션을 하나씩 순차적으로 실행하는 것처럼 보이게 만든다.
트랜잭션 예시
BEGIN
여러 개의 SQL 실행
COMMIT 또는 ROLLBACK