Foundry
데이터베이스
기초
핵심

ACID 속성

원자성, 일관성, 격리성, 지속성

ACID 속성

데이터베이스 트랜잭션이 안전하게 수행되기 위한 4가지 필수 속성

한눈에 보기

ACID = 데이터 무결성의 4대 보장

A - Atomicity   (원자성)  → 전부 or 전무
C - Consistency (일관성)  → 규칙 준수
I - Isolation   (격리성)  → 간섭 차단
D - Durability  (지속성)  → 영구 보존

1. Atomicity (원자성)

"All or Nothing", 전부 성공하거나 전부 취소

A 계좌에서 B 계좌로 10만원을 옮기는 트랜잭션입니다.

순서동작결과
1A 계좌에서 10만원을 뺀다성공
2B 계좌에 10만원을 넣는다실패

롤백하면 1번도 함께 취소되므로, A 에서만 빠지고 B 에는 들어가지 않는 상태를 막습니다.

2. Consistency (일관성)

트랜잭션 전후로 DB의 제약 조건이 항상 만족

[규칙] 잔고 >= 0

A 잔고: 5만원
A → B로 10만원 이체 시도

→ A 잔고 = -5만원 (규칙 위반!)
→ 트랜잭션 거부
→ DB는 항상 일관된 상태 유지

3. Isolation (격리성)

동시에 실행되는 트랜잭션끼리 서로 간섭하지 않음

[격리 없이]
Tx1: A 잔고 읽기 → 10만원
Tx2: A 잔고 읽기 → 10만원
Tx1: A -= 10만원 → 0원 (커밋)
Tx2: A -= 10만원 → 0원 (커밋)
→ 20만원이 빠져야 하는데 10만원만!

[격리 있으면]
Tx1이 A를 사용 중 → Tx2는 대기
→ 순차적으로 안전하게 처리

격리 수준: READ UNCOMMITTED → READ COMMITTED → REPEATABLE READ → SERIALIZABLE

4. Durability (지속성)

커밋된 데이터는 시스템 장애에도 보존

트랜잭션 커밋 완료!
  ↓
서버 전원 꺼짐 💥
  ↓
재시작 후 → 커밋 데이터 그대로!

[구현 방법]
WAL (Write-Ahead Log)
1. 변경 내용을 로그에 먼저 기록
2. 그 후 실제 데이터 변경
3. 장애 시 로그로 복구

ACID 위반 사례

위반현상ACID 속성
이체 중 에러돈이 증발Atomicity
잔고 마이너스규칙 깨짐Consistency
동시 수정 충돌데이터 덮어쓰기Isolation
커밋 후 유실데이터 사라짐Durability

NoSQL과 ACID

DB 유형ACID 지원
MySQL/PostgreSQL완전 지원
MongoDB (4.0+)멀티 문서 트랜잭션 지원
Redis단일 명령 원자적
DynamoDB조건부 (트랜잭션 API)

실무 연결

상황ACID 관련 포인트
결제 시스템ACID 필수 (돈 관련)
로그 수집일부 유실 허용 가능
MSASaga 패턴으로 분산 트랜잭션
성능 vs 안정성격리 수준으로 트레이드오프
면접에서 이렇게 나옵니다

Q.ACID 각 속성을 실제 예시와 함께 설명해주세요.

속성
원자성전부 되거나 전부 안 된다송금에서 출금만 되고 입금이 안 되는 상태가 없다
일관성규칙을 지킨 상태에서 다른 규칙을 지킨 상태로잔액이 음수가 되지 않는다, 외래키가 깨지지 않는다
격리성동시에 실행돼도 따로 실행한 것처럼두 사람이 같은 좌석을 동시에 예약하지 못한다
지속성커밋했으면 장애가 나도 남는다결제 완료 직후 서버가 죽어도 기록이 있다

일관성이 나머지 셋과 성격이 다릅니다. 원자성, 격리성, 지속성은 DB 가 보장하는 기능이지만 일관성은 그 결과이자 애플리케이션과의 약속입니다. 잔액이 음수면 안 된다는 규칙은 DB 가 스스로 알지 못하고 제약이나 코드로 표현해야 합니다.

흔한 실수: 일관성을 "데이터가 항상 최신"으로 설명하는 것. 그것은 분산 시스템의 일관성이고 여기서는 정의된 규칙을 위반하지 않는다는 뜻입니다.

Q.Atomicity는 어떻게 보장되나요? (Rollback)

변경 전 값을 따로 기록해 두었다가 실패 시 되돌립니다.

시점하는 일
UPDATE 전옛 값을 언두 로그에 남긴다
커밋언두 로그를 나중에 정리한다
롤백언두 로그의 옛 값으로 되돌린다

이 구조는 롤백만이 아니라 다른 트랜잭션의 읽기에도 쓰입니다. 아직 커밋되지 않은 변경을 다른 트랜잭션이 보면 안 되므로, 언두 로그에 있는 옛 값을 보여줍니다. 이것이 MVCC 의 기반입니다.

장애로 서버가 죽었을 때도 같은 원리로 복구합니다. 재시작 시 커밋되지 않은 트랜잭션의 변경을 언두 로그로 되돌립니다.

흔한 실수: 롤백을 "변경을 안 했던 것으로 되돌린다"고만 답하는 것. 옛 값을 어디에 보관했는지가 질문의 요지입니다.

Q.Durability는 DB 내부에서 어떻게 구현되나요? (WAL)

데이터 파일보다 로그를 먼저 디스크에 쓰는 방식으로 보장합니다.

1. 변경 내용을 로그에 적고 디스크에 반영한다
2. 커밋 응답을 보낸다
3. 실제 데이터 페이지는 나중에 모아서 디스크에 쓴다

데이터 파일을 매번 쓰면 무작위 위치에 흩어져 느립니다. 로그는 순차 쓰기라 훨씬 빠릅니다. 그래서 로그만 확실히 쓰고 데이터는 미뤄도 지속성이 성립합니다. 장애가 나면 로그를 다시 재생해 복구합니다.

성능과 안전의 조절점이 있습니다.

설정동작위험
커밋마다 로그를 디스크에 강제가장 안전가장 느리다
1초마다 모아서 강제빠르다장애 시 1초분 유실 가능

흔한 실수: 커밋하면 데이터 파일에 바로 쓴다고 답하는 것. 로그가 먼저이고 데이터는 나중이라는 순서가 핵심입니다.

Q.NoSQL에서도 ACID를 지원하나요?

많은 제품이 지원하지만 범위가 다릅니다.

제품범위
MongoDB단일 문서는 원래 원자적. 4.0 부터 다중 문서 트랜잭션 지원
DynamoDB단일 항목 원자적. 여러 항목 트랜잭션 API 제공
Cassandra파티션 단위의 경량 트랜잭션. 범위가 좁다
Redis명령 묶음이 순서대로 실행되지만 롤백은 없다

초기 NoSQL 이 ACID 를 포기한 이유는 분산 확장을 위해서였습니다. 여러 노드에 걸친 트랜잭션은 노드 간 합의가 필요해 느리고, 네트워크가 끊기면 멈춥니다.

지금은 대부분 단일 파티션 안에서는 ACID 를 주고, 파티션을 넘으면 비용이 크다는 것을 명시하는 형태입니다. 그래서 파티션 키 설계가 곧 트랜잭션 경계 설계가 됩니다.

흔한 실수: NoSQL 은 ACID 를 지원하지 않는다고 단정하는 것. 지금은 정확하지 않고, 어느 범위까지인지가 실제 질문입니다.

Q.은행 송금에서 트랜잭션이 없으면 어떤 문제가 생기나요?

중간에 실패하면 돈이 사라지거나 생깁니다.

순서동작여기서 실패하면
1A 계좌에서 10만원 출금아무 일도 없다
2B 계좌에 10만원 입금A 에서만 빠지고 B 에는 안 들어간다

트랜잭션이 있으면 2번 실패 시 1번도 함께 취소되어 원래 상태로 돌아갑니다.

동시성 문제도 있습니다. 잔액 10만원인 계좌에서 두 요청이 동시에 10만원을 출금하면, 둘 다 잔액을 확인한 뒤 각자 차감해 잔액이 마이너스가 될 수 있습니다. 이것은 원자성만으로는 부족하고 격리성이 필요한 문제입니다.

흔한 실수: 원자성만 말하고 격리성을 빼는 것. 실무 사고는 중간 실패보다 동시 실행에서 더 자주 납니다.

Q.분산 환경에서 ACID를 보장하기 어려운 이유는?

여러 노드가 함께 커밋할지 말지를 합의해야 하는데, 그 과정이 느리고 장애에 약하기 때문입니다.

2단계 커밋내용
1단계조정자가 모든 참가자에게 준비됐는지 묻는다
2단계모두 준비됐으면 커밋 명령을 보낸다
문제내용
지연노드 간 왕복이 여러 번. 가장 느린 노드에 맞춰진다
조정자 장애1단계 후 조정자가 죽으면 참가자들이 잠금을 쥔 채 멈춘다
가용성한 노드만 응답이 없어도 전체가 진행되지 않는다

그래서 실무에서는 강한 일관성을 포기하고 단계별로 처리하고 실패하면 보상하는 방식을 씁니다. 결제가 실패하면 이미 잡은 재고를 되돌리는 식입니다.

흔한 실수: 분산 트랜잭션이 불가능하다고 답하는 것. 가능하지만 비용이 커서 잘 안 쓴다는 것이 정확합니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

데이터베이스 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.