위키형 협업 편집, 동시 수정 충돌은 어떻게 막는가
위키의 권한 모델과 편집 워크플로를 정리하고, 비관적 잠금부터 CRDT까지 동시 편집 충돌 방지 방식을 비교한 뒤 HTTP ETag 기반 구현 예시로 마무리한다.
2026-08-12 · 최초 발행 2025-11-26
같은 문서를 동시에 고칠 때
위키는 웹 브라우저만으로 문서를 만들고 고치고 서로 링크할 수 있게 하는 협업 지식 관리 시스템이다. 읽기와 쓰기를 개방하고 협업을 중심에 둔 구조로 명쾌함(clarity)·간결성(brevity)·예의존중(decorum)을 지향하는 웹 애플리케이션이며, 온라인 백과사전이나 헬프데스크·FAQ·프로젝트 협업·지식베이스·정보 통합 도구에 두루 쓰인다.
참여자는 익명이든 인증 사용자든 읽기·쓰기 권한을 받되, 역할 기반 접근제어(RBAC)와 정책 기반 모더레이션 아래에서 움직인다. 편집이 일어나는 방식은 크게 두 갈래다. Thread Mode는 초기 문서에 대한 의견을 개진하는 토론 중심 모드로, 이슈 제기와 근거 링크 제시, 합의 형성을 목표로 하며 불필요한 중복·감정 표현은 최소화하는 규칙이 적용된다. Document Mode는 합의된 내용을 문서로 정제하는 공동 편집 모드로, 스타일 가이드와 템플릿을 준수하고 출처 표기 일관성을 확보하며 필요하면 리뷰어 승인 흐름을 선택적으로 붙인다.
문제는 여기서 시작된다. 같은 문서를 두 사람이 동시에 고치면 누구의 수정이 남는가.
누가 무엇을 할 수 있는가 — 권한과 거버넌스
역할 기반 권한(RBAC) 설계는 Reader·Contributor·Editor·Moderator·Admin으로 역할을 나누고, 페이지·네임스페이스·태그 단위로 권한 규칙을 정의하는 데서 시작한다. 여기에 실명·가명 정책, 스팸 방지(레이트 리밋·캡차), 신고·차단 플로우, 감사 로그와 변경 이력 투명성 확보 같은 정책 기반 거버넌스가 얹힌다.
동시성을 지키는 방법
Thread Mode의 토론은 순서만 지키면 되지만, Document Mode의 본문 편집은 충돌을 피할 수 없다. 위키가 실제로 쓰는 동시성 제어 방식은 크게 넷이다.
| 방법 | 성능 | 확장성 | 일관성 | 안정성 | 운영 편의 |
|---|---|---|---|---|---|
| 비관적 잠금(전체/섹션) | 단일 편집 시 우수 | 노드 증가 시 잠금 경합 | 강한 일관성 | 데드락 예방 필요 | 운영 단순 |
| 낙관적(ETag/If-Match) | 일반적 우수 | 수평 확장 용이 | 충돌 시 사용자 병합 필요 | 네트워크 불안정 내성 보통 | 구현 간결 |
| OT(Operational Transformation) | 저지연 우수 | 서버 자원 요구↑ | 강한 실시간 일관성 | 충돌 처리 성숙 | 구현 복잡 |
| CRDT | 네트워크 분할 내성 우수 | 엣지/오프라인 확장 강점 | 최종 일관성(Eventual) | 메모리 오버헤드 감수 | 도입 난이도 높음 |
저장 시점의 충돌은 낙관적 동시성 제어(ETag/If-Match)와 구간 잠금(Section Lock)을 병행해 잡아낸다. 저장 시 충돌을 탐지하면 3-way 머지로 해결을 시도한다. 실시간 협업까지 필요하다면 OT(Operational Transformation)나 CRDT 적용을 검토해야 하는데, 이때는 데이터 정합성과 네트워크 분할 내성, 복구 전략을 함께 고려해야 한다.
저장에서 공개까지, 아키텍처 흐름
절차로 보면
입력 단계에서는 사용자 의도(토론 개시인지 문서 편집인지)를 식별하고 인증·권한을 검증한 뒤 기반 문서와 메타데이터를 로드한다. 처리 단계에서는 선택된 편집 모드를 적용하고 동시성 제어(ETag·락·OT·CRDT 중 하나)를 거치며 링크·출처·길이·금지어 같은 품질 규칙을 검사한다. 출력 단계에서는 새 버전을 생성하고 알림·감시를 트리거하며 검색 인덱스를 갱신하고 감사 로그를 남긴다. 오류가 나면 충돌 해결 절차를 수행하고 사용자에게 피드백을 준다.
문서가 자라날 때 — 구조화와 리팩토링
문서량이 늘면 카테고리·태그·백링크·자동 목차·템플릿·매크로·트랜스클루전 같은 구조화 메커니즘이 필요해진다. 여기에 중복 문서 통합, 단위 문서 분리, 리디렉션·디스앰비규에이션, 깨진 링크 자동 검증·정정 같은 리팩토링 절차가 뒤따른다.
버전과 감시 체계
변경 이력을 저장하고 diff를 시각화하며 롤백·재적용 기능을 제공하는 한편, 워치리스트·웹훅 기반의 변경 알림과 구독형 감시 체계를 갖춘다. 문서 최신성, 출처 신뢰도, 링크 건전성, 편집자 다양성 같은 품질 지표를 모니터링하고 대시보드화하는 것도 이 층의 몫이다.
실무에서 위키가 쓰이는 곳
온라인 백과사전(위키피디아류)은 대규모 기여자 기반 위에 엄격한 가이드라인과 반달리즘 대응 자동화를 얹은 형태다. 헬프데스크·FAQ에서는 반복 이슈를 빠르게 문서화하고 티켓과 백링크를 자동 연결하며 해결책 최신화를 SLA와 엮는다. 프로젝트 협업 도구로 쓸 때는 결정 기록(ADR), 회의록 템플릿, 릴리스 노트 트랜스클루전, 리뷰 워크플로 연계가 핵심이다. 사내 지식베이스에서는 온보딩 가이드와 표준 운영절차(SOP), 보안·컴플라이언스 근거를 관리하고, 정보 통합 허브로 쓸 때는 데이터 소스 요약·정규화와 용어집·디스앰비규에이션, 서비스 카탈로그 중앙화가 목적이 된다.
도입 효과
중복 답변·문서가 줄면서 생산성은 2040% 개선을, 이슈 해결 리드타임은 1530% 단축을 기대할 수 있다. 출처·리뷰 기반으로 신뢰도가 오르고 변경 가시성 덕분에 회귀 결함도 줄어든다. 검색 성공률이 오르고 온보딩 교육 시간이 줄며 커뮤니케이션 소음도 감소한다. 감사 추적이 가능해지고 정책 준수율을 측정·개선하기도 쉬워진다.
HTTP ETag로 낙관적 동시성 직접 구현하기
전제조건은 Node.js 18+와 Express 4.x, 이 예시에서는 메모리 저장소를 쓴다. 실제 환경이라면 DB 버전 필드와 트랜잭션 적용을 권장한다.
// npm i express etag
const express = require("express");
const etag = require("etag");
const app = express();
app.use(express.json());
const store = new Map(); // { id: { body, version } }
app.get("/doc/:id", (req, res) => {
const d = store.get(req.params.id) || { body: "", version: 0 };
const body = d.body;
const ETag = etag(body + d.version);
res.set("ETag", ETag).status(200).send(body);
});
app.put("/doc/:id", (req, res) => {
const d = store.get(req.params.id) || { body: "", version: 0 };
const currentETag = etag(d.body + d.version);
const ifMatch = req.get("If-Match");
if (!ifMatch || ifMatch !== currentETag) {
return res
.status(412)
.json({ error: "Precondition Failed", hint: "Fetch latest and merge" });
}
const next = { body: req.body.body || "", version: d.version + 1 };
store.set(req.params.id, next);
res
.set("ETag", etag(next.body + next.version))
.status(200)
.json({ ok: true, version: next.version });
});
app.listen(3000, () => console.log("wiki demo on :3000"));
프런트엔드는 저장이 412로 실패했을 때 Diff/3-way Merge UI를 보여줘야 한다. 백엔드는 문서 단위가 아니라 섹션 키 단위로 ETag를 나누면 충돌률을 추가로 낮출 수 있다. 배포 시 리버스 프록시 캐시를 쓴다면 ETag 재검증(If-None-Match)과 혼동하지 않도록 설정해야 한다.
보안·운영에서 놓치기 쉬운 트레이드오프
인증은 OIDC/SAML 기반 SSO와 RBAC를 병행하는 것이 기본이다. 익명 편집을 허용하면 속도는 빨라지지만 악성 편집 리스크가 늘어나는 트레이드오프가 따른다. 무결성과 가용성을 위해서는 자동 백업과 증분 스냅샷, 버전 고정 스토리지, 필요하면 WORM 옵션까지 검토할 수 있는데, 보호를 강하게 할수록 비용과 복구 시간은 늘어난다. 스타일 가이드와 템플릿을 강제하면 콘텐츠 일관성은 확보되지만 편집자의 자율성은 떨어지므로, 가벼운 린트 규칙부터 점진적으로 강화하는 편이 낫다. 편집 이벤트 스트림(웹훅·큐)과 검색 인덱스 상태를 관찰하는 체계는 지연을 최소화하려면 비동기 파이프라인으로 설계해야 한다.