MongoDB의 ACID 완전 정복 Part 1 — "NoSQL도 트랜잭션이 된다고?" ACID 개념과 MongoDB의 진화
NoSQL이라 트랜잭션이 없다는 이야기는 MongoDB에는 더 이상 정확하지 않습니다. 다만 역사적으로는 단일 문서 원자성과 멀티 문서·분산 트랜잭션의 범위가 단계적으로 넓어졌고, 그 과정을 알아야 지금 매뉴얼이 말하는 보장의 한계도 읽을 수 있습니다. 이 Part 1에서는 ACID 네 글자를 실무 질문에 연결해 풀고, 4.0·4.2 전후 타임라인을 정리합니다. CAP 이야기는 흔히 쓰이는 두 개 선택 공식에만 머물지 않고, 분산 환경에서 무엇이 전제인지 짚습니다. 또한 트랜잭션을 도입할 때 따라오는 경합·지연·재시도 비용과, 단일 문서로 설계할 수 있는지부터 점검하는 짧은 의사결정 흐름을 덧붙였습니다. 이후 파트에서 Atomicity·Isolation·Durability를 각각 깊게 다룰 받침이 됩니다.
시리즈 구성
- Part 1 ← 지금 여기 | ACID 개념 + MongoDB의 역사적 맥락
- Part 2 — Atomicity & Consistency 심층 분석 + 단일 문서 vs 멀티 문서
- Part 3 | Isolation 레벨과 Snapshot Isolation 내부 동작
- Part 4 | Durability, WiredTiger 스토리지 엔진, Write Concern (출간 예정)
- Part 5 | 실전 코드 패턴 + 성능 최적화 + 안티패턴 (출간 예정)
목차
- 들어가며 — "NoSQL도 트랜잭션?"
- ACID란 무엇인가?
- MongoDB와 ACID — 오해와 진화의 역사
- 왜 NoSQL에서 ACID가 어려운가 — CAP 너머, 그리고 트랜잭션의 비용
- 언제 멀티 문서 트랜잭션이 필요한가 — 짧은 의사결정 흐름
- 마치며 — Part 1 요약
1. 들어가며 — "NoSQL도 트랜잭션?"
2018년, MongoDB가 버전 4.0을 출시하면서 기술 커뮤니티는 꽤 충격을 받았습니다.
"NoSQL이 ACID 트랜잭션을 지원한다고?"
그로부터 시간이 지난 지금, MongoDB는 단순한 'NoSQL 데이터베이스'라는 꼬리표만으로 설명하기 어려운 제품이 되었습니다. 멀티 문서 ACID 트랜잭션, 고가용성 구성, 보안·규정 준수 기능까지 — 금융·헬스케어·이커머스 등에서 MongoDB를 미션 크리티컬 스택의 한 축으로 두는 공개 사례도 늘었습니다. 다만 "시장에서 항상 1순위"처럼 단일 지표로 단정하기는 어렵습니다. 채용, 레퍼런스, 워크로드마다 선택 이유가 다르고, 규제·SLA·기존 인력 같은 제약이 먼저입니다.
이 시리즈는 MongoDB의 ACID를 표면적인 개념 설명에서 끝내지 않고, 내부 동작과 실무 트레이드오프까지 파고드는 것을 목표로 합니다. 그 첫걸음으로 이번 글에서는 ACID가 무엇을 요구하는지, 그리고 MongoDB가 언제부터 어떤 범위로 그 요구를 충족해 왔는지를 정리합니다.
2. ACID란 무엇인가?
데이터베이스를 처음 공부할 때 누구나 한 번쯤 외우는 네 글자입니다. 실무에서 이름만 알고 쓰는 경우도 많습니다. 여기서는 각각을 운영 중인 시스템에 던질 질문으로 바꿔 봅니다.
Atomicity (원자성)
트랜잭션 안의 모든 연산은 전부 성공하거나, 전부 실패해야 합니다.
계좌 이체를 생각해 보겠습니다. A 계좌에서 금액을 차감하고 B 계좌에 더하는 두 연산이 있을 때, 차감만 되고 가산이 실패하면 자금이 사라집니다. Atomicity는 이런 반쪽 실행을 막습니다.
Consistency (일관성)
트랜잭션 실행 전후로 데이터베이스는 규칙이 허용하는 상태를 유지해야 합니다. 스키마·도메인 규칙·무결성 제약이 깨지지 않아야 한다는 뜻입니다. (문맥에 따라 "애플리케이션이 정의한 불변식"을 가리키기도 합니다.)
Isolation (격리성)
동시에 실행되는 트랜잭션들은 서로의 중간 상태를 관찰할 수 없어야 합니다. 마치 혼자 실행되는 것처럼 보이게 만드는 성질입니다. 실제로는 격리 수준에 따라 허용되는 현상(더티 리드, 팬텀 등)이 달라집니다. MongoDB의 세부 동작은 이후 Part 3에서 다룹니다.
Durability (지속성)
한번 성공적으로 커밋된 결과는 이후 장애가 나도 유실되지 않아야 합니다. "저장됐다"고 응답한 데이터가 서버 재시작 뒤에도 남아 있어야 합니다. 디스크·복제·Write Concern 같은 주제는 Part 4로 이어집니다.
3. MongoDB와 ACID — 오해와 진화의 역사
3.1 초기 (2009~2017): "NoSQL = ACID가 없다?"
MongoDB가 처음 등장했을 때는 "웹 스케일"과 "유연한 스키마"가 강조되곤 했습니다. 당시에는 여러 컬렉션에 걸친 멀티 문서 트랜잭션이 없었고, 그 점이 비판 근거가 되기도 했습니다.
그러나 **"ACID가 전혀 없었다"**로 요약하면 기술적으로 어긋납니다. MongoDB는 그 시기에도 단일 문서(single document) 단위에서는 읽기·쓰기가 함께 적용되거나 전부 롤백되는 원자적 갱신을 보장했습니다. 중첩 배열·서브도큐먼트를 포함한 하나의 BSON 문서는 하나의 원자 단위로 다뤄질 수 있었습니다. 논쟁의 축은 "ACID 자체의 유무"보다 어디까지가 트랜잭션 경계로 공식 지원되느냐에 가까웠습니다.
3.2 전환점: MongoDB 4.0 (2018) — Replica Set에서 멀티 문서 ACID
2018년 6월, MongoDB 4.0과 함께 멀티 문서 ACID 트랜잭션이 도입되었습니다. Replica Set 환경에서 여러 문서·컬렉션에 걸친 트랜잭션이 가능해졌습니다.
3.3 MongoDB 4.2 (2019) — Sharded Cluster로 확장
4.0이 Replica Set에 한정되었다면, 4.2는 샤딩된 클러스터 전체에서도 ACID 트랜잭션 범위를 넓혔습니다. 수평 확장을 유지한 채 트랜잭션을 쓰는 시나리오를 열어 준 릴리스로 이해할 수 있습니다.
| 버전 | 시기(대략) | 트랜잭션 관련 메모 |
|---|---|---|
| ~3.x | ~2017 이전 | 멀티 문서 트랜잭션은 애플리케이션/패턴으로 우회하는 경우가 많았음 |
| 4.0 | 2018 | Replica Set — 멀티 문서 ACID |
| 4.2 | 2019 | Sharded Cluster — 분산 트랜잭션 |
| 이후 | 2020~ | 성능·운영 개선, 제품 기능 확대(버전별 릴리스 노트 참고) |
버전별 정확한 제약은 배포 형태(standalone vs replica set vs sharded)마다 다르므로, 항상 사용 중인 버전의 공식 매뉴얼을 기준으로 삼는 것이 안전합니다.
3.4 지금 — 어떻게 읽을 것인가
오늘날 MongoDB는 엔터프라이즈 워크로드에서 흔히 검토되는 선택지 중 하나로 자리 잡았습니다. 다만 도입 여부는 지표 하나가 아니라 규제, 다운타임 허용치, 팀 역량, 기존 스택과의 궁합으로 결정됩니다. "모든 금융권이 MongoDB만 쓴다" 같은 문장은 경험과 어긋날 수 있으니, 공개 레퍼런스와 본인 조직의 제약을 함께 놓고 보는 편이 좋습니다.
4. 왜 NoSQL에서 ACID가 어려운가 — CAP 너머, 그리고 트랜잭션의 비용
4.1 CAP와 분산 환경
CAP 정리는 흔히 일관성(Consistency)·가용성(Availability)·분할 내성(Partition tolerance) 중 두 가지만 고를 수 있다는 식으로 소개됩니다. 다만 엄밀히 말하면, 여기서 말하는 전제는 네트워크가 분할(partition)된 상황이고, "평소에는 모두 만족에 가깝게 가다가, 분할 시에 어떤 쪽을 우선할지"에 가까운 논의입니다. 모든 운영 시나리오를 세 글자로 끝내기 어렵다는 점은 기억해 두는 것이 좋습니다.
초기 MongoDB를 포함한 많은 분산 데이터 스토어는 강한 동기적 일관성을 모든 연산에 강제하기보다, 지연·가용성·확장성과의 균형을 다른 쪽에 두는 설계 선택을 해 왔습니다. ACID 트랜잭션, 특히 여러 노드에 걸친 트랜잭션은 동기화와 합의 비용이 따라붙을 수밖에 없습니다.
4.2 도큐먼트 모델과 "자연스러운" 원자성
MongoDB의 도큐먼트 모델은 설계에 따라 멀티 문서 트랜잭션을 줄일 수 있는 면이 있습니다. 관계형 모델에서 여러 테이블로 나뉘던 데이터를 하나의 문서에 담을 수 있다면, 그 문서에 대한 갱신은 단일 문서 원자성만으로도 요구를 만족시키는 경우가 많습니다.
// 한 주문을 하나의 도큐먼트로 모델링한 예 (개념용)
{
_id: ObjectId("..."),
orderId: "ORD-2026-001",
customerId: "CUST-123",
status: "confirmed",
items: [
{ productId: "PROD-A", qty: 2, price: 15000 },
{ productId: "PROD-B", qty: 1, price: 32000 }
],
totalAmount: 62000,
createdAt: ISODate("2026-04-09T00:00:00.000Z")
}
이렇게 경계를 문서 안에 담을 수 있다면, 굳이 여러 컬렉션을 한 트랜잭션으로 묶지 않아도 됩니다. "스키마를 넓게 잡는 대신 트랜잭션 의존도를 낮춘다"는 전략은 여전히 유효합니다.
4.3 멀티 문서 트랜잭션을 쓸 때의 비용
트랜잭션이 "가능해졌다"는 사실만큼, 언제 비싸지는지를 아는 것도 중요합니다.
- 경합: 같은 문서·같은 인덱스 범위를 동시에 건드리면 대기와 재시도가 늘어납니다.
- 지연: 합의·로깅·락 획득은 네트워크 RTT와도 맞물립니다.
- 재시도: 클라이언트는
TransientTransactionError등에 대응하는 재시도 정책을 설계해야 하는 경우가 많습니다. - 배포 토폴로지: 샤드 키·세션·세션 타임아웃 같은 운영 변수가 성격에 영향을 줍니다.
즉 "필요할 때만 쓰고, 가능하면 단일 문서 설계로 피한다"가 기본선에 가깝습니다. 세부 튜닝과 패턴은 Part 5에서 다루기로 하고, 여기서는 비용이 있다는 사실만 고정해 두겠습니다.
5. 언제 멀티 문서 트랜잭션이 필요한가 — 짧은 의사결정 흐름
아래는 절대 규칙이 아니라, 설계 리뷰에서 자주 쓰는 질문 순서입니다.
-
필요한 상태를 하나의 도큐먼트로 모델링할 수 있는가?
→ 예: 중첩 배열·서브도큐먼트만 갱신하면 되는 경우, 단일 문서 연산으로 충분한 경우가 많습니다. -
서로 다른 컬렉션(또는 문서) 사이에 "동시에 만족해야 하는" 불변식이 있는가?
→ 예: 재고 차감과 주문 확정, 이체 출금과 입금. 이때는 멀티 문서 트랜잭션을 후보에 올립니다. -
경합이 심한 핫 키인가?
→ 예: 트랜잭션을 쓰더라도 설계·샤딩·집계 전략을 같이 봐야 합니다. 트랜잭션만으로 모든 동시성 문제가 해결되지는 않습니다. -
실패 시 애플리케이션은 재시도·보상 트랜잭션을 감당할 수 있는가?
→ 분산 환경에서는 "한 번에 성공"만 가정하기 어렵습니다.
멀티 문서가 반드시 필요한 전형 예
- 계좌 이체처럼 서로 다른 문서의 잔액을 맞춰야 하는 경우
- 주문과 재고처럼 컬렉션이 나뉜 불변식을 한 번에 맞춰야 하는 경우
단일 문서 원자성으로 자주 처리되는 예
$push/$pull로 배열 항목 추가·삭제$set으로 여러 필드 동시 갱신$inc로 카운터 조정
6. 마치며 — Part 1 요약
| 키 포인트 | 요약 |
|---|---|
| ACID | Atomicity, Consistency, Isolation, Durability — 각각이 요구하는 것을 운영 질문으로 바꿔 이해합니다. |
| MongoDB의 역사 | 단일 문서 원자성은 이전부터 존재했고, 멀티 문서·분산 범위가 버전을 따라 넓어졌습니다. |
| 4.0 / 4.2 | Replica Set → Sharded Cluster 순으로 공식 지원이 확장되었습니다. |
| 설계 철학 | 문서 경계 안에 넣을 수 있는지 먼저 보고, 불가피할 때 멀티 문서 트랜잭션을 고려합니다. |
| 다음 단계 | 트랜잭션 비용(경합·재시도)을 전제로, Part 2에서 Atomicity·Consistency를 더 깊게 짚습니다. |
다음 편에서는 Atomicity와 Consistency를 중심으로, 단일 문서 연산과 멀티 문서 트랜잭션이 어떻게 다른지, 롤백과 오류 코드는 무엇을 의미하는지 살펴볼 예정입니다.
참고·출처
- MongoDB Manual — 단일 문서·쓰기 연산의 원자성(Atomicity)
- MongoDB Manual — Transactions
- MongoDB Manual — 릴리스 노트 4.0 — 멀티 문서 트랜잭션
- MongoDB Manual — 릴리스 노트 4.2 — 분산 트랜잭션
- MongoDB Manual — 애플리케이션에서의 트랜잭션·재시도 (
TransientTransactionError등) - MongoDB Manual — 업데이트 연산자 (
$set,$push,$inc등) - CAP 정리 — 흔한 “세 가지 중 두 가지” 요약과 달리, 네트워크 분할(partition) 상황에서의 트레이드오프로 읽는 편이 안전합니다(일반적인 분산 시스템 문헌).
작성: 2026년 4월 · 제품 버전·라이선스·클라우드 요금은 시점에 따라 달라질 수 있으니, 인용 시 공식 문서와 릴리스 노트를 확인하세요.