CS Fundamentals

트랜잭션과 ACID에 대해서 설명해주세요

계좌 이체 하나로 배우는 원자성, 일관성, 격리성, 지속성. 트랜잭션이 실패해도 데이터가 안전한 이유를 인터랙티브 시뮬레이션으로 체험합니다.

2026년 3월 11일 · 약 12분 읽기

Q. "데이터베이스 트랜잭션이 무엇인지, 그리고 ACID 속성에 대해 설명해주세요."

예상 꼬리질문

답변 가이드

"트랜잭션은 '전부 성공하거나 전부 실패해야 하는' 논리적 작업 단위입니다. ACID는 Atomicity(원자성) · Consistency(일관성) · Isolation(격리성) · Durability(지속성)의 약자로, 트랜잭션이 안전하게 처리되기 위한 네 가지 보장입니다."

"Undo Log가 원자성을, WAL(Write-Ahead Log)가 지속성을 구현합니다. 장애가 나도 커밋된 데이터는 살아남습니다."

"격리 수준이 높을수록 데이터 정확성은 올라가지만 성능은 낮아집니다. MVCC는 읽기와 쓰기가 서로 블로킹하지 않도록 데이터의 여러 버전을 유지하는 핵심 기법입니다."

은행 앱에서 송금 버튼을 눌렀을 때, 내 계좌에서 돈이 빠져나간 뒤 상대방 계좌에 입금되지 않는 상황은 일어나지 않습니다. 데이터베이스 트랜잭션이 ACID 속성을 보장하기 때문입니다.

1983년 처음 정의된 이 네 가지 약속이 어떻게 동작하는지, 직접 시뮬레이션으로 체험해 봅니다.


1. ACID — 트랜잭션이 지켜야 할 네 가지 약속

꼬리질문: "ACID의 네 가지 속성을 각각 설명해주세요"

트랜잭션(Transaction)은 하나의 논리적 작업 단위입니다. 계좌 이체처럼 여러 DB 연산이 반드시 함께 성공하거나 함께 실패해야 하는 경우, 이 연산들을 하나로 묶은 것이 트랜잭션입니다.

각 속성 카드를 클릭해 "이 속성이 없다면 어떤 일이 벌어지는지" 확인해 보세요.

트랜잭션 내 모든 연산은 전부 성공하거나 전부 실패합니다. 중간 상태는 허용되지 않습니다.

이 속성이 없다면?

출금은 됐는데 입금이 안 된다면?

구현 메커니즘Undo Log

2. 원자성 — 절반만 실행된 트랜잭션은 없다

꼬리질문: "원자성은 내부적으로 어떻게 구현되나요?"

원자성은 트랜잭션 내 모든 연산이 전부 성공(COMMIT)하거나 전부 취소(ROLLBACK)됨을 보장합니다. 데이터베이스는 Undo Log에 변경 전 값을 미리 기록해 두었다가, 오류가 발생하면 이를 이용해 원래 상태로 되돌립니다.

A에서 B로 10만 원을 이체하는 트랜잭션을 직접 실행해 보세요. "정상 실행"과 "중간에 오류 발생" 두 시나리오를 비교하면 원자성이 왜 필요한지 바로 보입니다.

A 계좌

500,000

B 계좌

300,000

트랜잭션 진행 단계

1

START TRANSACTION

START TRANSACTION;

2

A 계좌 출금

UPDATE accounts SET balance = balance - 100000 WHERE id = 'A';

3

B 계좌 입금

UPDATE accounts SET balance = balance + 100000 WHERE id = 'B';

4

COMMIT

COMMIT;

트랜잭션 상태: 대기 중

롤백이 완료된 뒤 A 계좌 잔액이 원래대로 복원되는 것을 확인하세요. 중간에 오류가 났어도 데이터베이스는 "아무 일도 없었던 것처럼" 상태를 되돌립니다.

3. 격리성 — 동시 실행 트랜잭션이 충돌하지 않으려면

꼬리질문: "격리 수준(Isolation Level)의 종류와 트레이드오프를 설명해주세요"

수천 명이 동시에 같은 데이터에 접근할 때, 트랜잭션들이 서로의 중간 상태를 읽으면 Dirty Read, Non-Repeatable Read, Phantom Read 같은 문제가 발생합니다. SQL 표준은 이 문제들을 얼마나 허용할지를 4가지 격리 수준(Isolation Level)으로 정의합니다.

격리 수준 탭을 순서대로 탐색하며 각 수준이 어떤 문제를 허용하고 차단하는지 확인해 보세요.

가장 낮은 격리 수준. 커밋되지 않은 데이터도 읽을 수 있어 세 가지 문제 모두 발생 가능합니다. 실무에서는 거의 사용하지 않습니다.

동시성 문제 발생 여부

발생

Dirty Read

커밋되지 않은 데이터를 읽음. T2가 롤백되면 T1이 읽은 값은 유령 데이터가 됩니다.

발생

Non-Repeatable Read

같은 행을 두 번 읽었을 때 값이 달라짐. 중간에 다른 트랜잭션이 UPDATE/COMMIT한 경우.

발생

Phantom Read

같은 조건으로 조회했을 때 행 수가 달라짐. 중간에 다른 트랜잭션이 INSERT/COMMIT한 경우.

전체 격리 수준 비교

격리 수준Dirty ReadNon-RepeatablePhantom Read
READ UNCOMMITTED발생발생발생
READ COMMITTED방지발생발생
REPEATABLE READ방지방지방지
SERIALIZABLE방지방지방지

MySQL InnoDB의 기본값인 REPEATABLE READ는 MVCC(Multi-Version Concurrency Control)를 활용해 Phantom Read까지 방지합니다. PostgreSQL의 기본값 READ COMMITTED는 커밋된 데이터만 읽되, 같은 트랜잭션 내에서도 최신 커밋을 반영합니다.

4. 지속성 — 커밋된 데이터는 절대 사라지지 않는다

꼬리질문: "WAL이 무엇이고 지속성을 어떻게 보장하나요?"

커밋 직후 서버 전원이 꺼져도 데이터가 살아있는 비밀은 WAL(Write-Ahead Logging)입니다. 데이터베이스는 실제 데이터 파일에 쓰기 전에 WAL Log에 먼저 변경 내용을 기록하고, 장애 복구 시 이 로그를 재실행(Redo)합니다.

"커밋 실행 → 장애 발생 → 복구 시작" 순서로 버튼을 눌러 WAL 기반 복구 과정을 직접 체험해 보세요.

Memory Buffer

휘발성 — 장애 시 소실

WAL Log

디스크 — 장애 후에도 유지

Data File

디스크 — 실제 데이터

balance = 500,000원

대기 중 — "커밋 실행" 버튼을 눌러 시작하세요

WAL (Write-Ahead Logging) 원리

1. 데이터 변경 전 WAL Log에 먼저 기록
2. COMMIT 시 WAL을 디스크에 fsync()
3. Data File은 비동기로 나중에 반영
4. 장애 시 WAL Log로 Redo 실행 → 복구

Memory Buffer는 장애로 소실되지만, WAL Log는 디스크에 남아 있어 커밋된 데이터를 복원합니다. MySQL의 innodb_flush_log_at_trx_commit=1 설정이 커밋마다 WAL을 디스크에 fsync()하는 이 동작을 보장합니다.


면접 체크리스트

이 항목들을 자신 있게 설명할 수 있다면 트랜잭션/ACID 질문은 준비 완료입니다.

  • - ACID 4가지: Atomicity(Undo Log) · Consistency(제약 조건) · Isolation(MVCC/Lock) · Durability(WAL)
  • - 원자성 구현: Undo Log로 롤백 — 오류 발생 시 원래 상태로 복원
  • - 격리 수준: 성능과 정합성의 트레이드오프 — 상황에 맞는 수준 선택
  • - MVCC: 읽기와 쓰기가 서로 블로킹하지 않도록 하는 핵심 기법
  • - WAL: 디스크 쓰기 전에 로그 먼저 기록 — 장애 복구의 기반

참고 자료


의견을 들려주세요

서비스 개선에 큰 도움이 됩니다. 익명으로 자유롭게 남겨주세요.

0 / 1000