여러 작업을 하나의 논리 단위로 묶어 전부 되거나 전부 안 되게 만드는 약속. 네 글자의 머리글자다.
네 가지
| 뜻 | 무엇으로 구현되나 | |
|---|---|---|
| Atomicity 원자성 | 전부 아니면 전무. 중간 실패 시 모두 롤백 | undo 로그·WAL |
| Consistency 일관성 | 트랜잭션 전후로 제약(무결성·FK·CHECK)이 유지 | 나머지 셋이 받쳐 주는 결과적 속성 |
| Isolation 독립성 | 동시 트랜잭션이 서로 안 보이는 것처럼 | 격리수준·락·MVCC |
| Durability 지속성 | 커밋된 것은 장애가 나도 살아남는다 | WAL을 디스크에 먼저 flush |
BEGIN;
UPDATE account SET balance = balance - 10000 WHERE id = 'A';
UPDATE account SET balance = balance + 10000 WHERE id = 'B';
COMMIT; -- 둘 다 확정. 사이에서 죽으면 롤백되어 A도 원복된다
네 글자가 같은 무게가 아니다
일관성(C)은 나머지 셋과 성격이 다르다. 원자성·독립성·지속성은 DB가 제공하는 메커니즘이지만, 일관성은 그 셋과 애플리케이션의 제약 정의가 함께 만들어 내는 결과다. "C만 따로 구현하는 장치"는 없다.
그리고 실무에서 어려운 건 I 하나다. A·D는 로그로 해결되고 조정할 여지가 거의 없지만, I는 성능과 정면으로 맞바꾸는 선택지(격리수준)를 열어 둔다.
분산에서는 무엇이 달라지나
-
단일 DB — ACID — 강한 일관성을 바로 보장 분산 시스템 BASE — Basically Available, Soft state, Eventually consistent
- 즉시 일관성 대신 가용성과 확장성을 택한다
면접 함정
- ❌ "일관성은 데이터가 정확하다는 뜻" → 정의된 제약이 깨지지 않는다는 뜻이다. 값이 업무적으로 옳은지는 DB가 모른다.
- ❌ "ACID면 동시성 문제가 없다" → 격리수준을 낮추면 이상현상이 그대로 샌다.
실제로 어디까지 보장되나 — 확인해 보기
-- 원자성: 중간에 실패시켜 본다
BEGIN;
UPDATE account SET balance = balance - 10000 WHERE id = 'A';
SELECT 1/0; -- 강제 오류
COMMIT; -- PostgreSQL: 트랜잭션이 이미 abort 상태 → 전부 롤백
SELECT balance FROM account WHERE id='A'; -- 원래 값 그대로
PostgreSQL은 트랜잭션 안에서 오류가 나면 그 트랜잭션 전체가 중단 상태가 되어 이후 문장이 모두 거부된다. MySQL은 문장 단위로 실패하고 트랜잭션은 살아 있어, 애플리케이션이 명시적으로 롤백해야 한다 — 같은 코드가 두 엔진에서 다르게 동작하는 대표적 지점이다.
지속성은 설정으로 흥정된다
-- PostgreSQL: 커밋 시 WAL 을 디스크에 flush 할 것인가
SHOW synchronous_commit; -- on (기본) → 완전한 지속성
SET synchronous_commit = off; -- 성능↑, 대신 크래시 시 최근 몇 밀리초를 잃을 수 있다
-- MySQL: 1(기본·매 커밋 flush) / 2(OS 캐시까지) / 0(1초마다)
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
D는 켜고 끌 수 있는 값이다. 로그성 테이블처럼 몇 건 잃어도 되는 데이터는 이걸 낮춰 쓰기 성능을 크게 올린다 — ACID가 전부 아니면 전무가 아니라는 걸 보여주는 실무 지점이다.