한 명 이상의 작성자가 동시에 문서를 업데이트할 수 있는 복제 환경에서는 충돌이 발생할 수 있습니다. 특히 모바일 환경에서는 네트워크 연결이 불안정하여 여러 장치에서 동시에 변경한 내용이 적시에 동기화되지 않아 충돌이 발생할 수 있습니다.
이 글에서는 카우치베이스 모바일에서 충돌이 처리되는 방식에 대한 기본 사항을 설명하고 충돌을 해결하는 데 있어 애플리케이션의 역할을 간략하게 설명합니다. 다음 글에서는 리비전 기반 문서 관리 시스템에서 리비전 트리와 데이터베이스 크기를 관리하는 관련 주제에 대해 설명합니다.
이 블로그에서 설명하는 충돌 해결 프로세스는 Couchbase Mobile 1.x에 적용됩니다. post 의 자동 충돌 해결 프로세스에 대한 자세한 내용은 카우치베이스 모바일 2.x의 문서 를 참조하여 Couchbase Mobile 2.x의 사용자 지정 충돌 해결에 대해 논의하세요.
아래 그림은 모바일 환경에서 충돌이 발생할 수 있는 시나리오를 설명합니다.

배경
그리고 카우치베이스 모바일 스택에는 카우치베이스 라이트 장치에서 로컬로 실행되는 임베디드 데이터베이스와 동기화 게이트웨이 클라우드에서 일반적으로 지원되는 카우치베이스 서버 클라우드에서 데이터를 유지합니다. 동기화 게이트웨이는 여러 장치에 걸친 문서 복제를 처리합니다. 하나의 문서를 여러 장치에서 동시에 업데이트할 수 있습니다.
다중 버전 동시성 제어
카우치베이스 모바일은 다중 버전 동시성 제어(MVCC) 기술을 사용하여 충돌을 처리합니다. 이 방식에서는 모든 문서에 시스템에서 생성된 고유한 리비전 ID가 할당됩니다. 이 ID는 문서 수정본에 걸쳐 동일하게 유지되는 문서 ID에 추가됩니다. 수정이든 삭제든 문서에 대한 모든 변경은 문서의 새 수정본으로 간주되므로 새 수정본 ID가 할당됩니다.
리비전 트리
기존 문서를 변경할 때마다 작성자는 업데이트 중인 문서의 현재 리비전 ID를 포함해야 합니다. 변경 사항에 대한 새 리비전이 생성되고 업데이트 중인 현재 리비전의 하위 노드로 추가되어 문서의 리비전 트리가 생성됩니다.
모든 문서에는 문서의 수명에 따라 커지는 리비전 트리가 있습니다. 다음 글에서 수정본 트리의 크기를 관리하는 방법에 대해 설명할 예정이니 기대해 주세요!
문서 구조
매우 높은 수준에서 보면 Couchbase Mobile V1.4의 모든 문서는 문서 ID, 현재 수정본 ID, JSON 본문 및 메타데이터로 구성됩니다. 메타데이터는 무엇보다도 문서의 리비전 히스토리를 담고 있습니다. 메타데이터는 '비하인드' 개념이므로 사용자 애플리케이션은 메타데이터에 대해 걱정할 필요가 없습니다. 실제로 향후 버전 를 사용하면 메타데이터가 문서에서 완전히 벗어나 XATTR로 이동합니다.
또한 모든 문서 수정본에는 관련 TTL 값(기본값은 5분)이 있습니다.
묘비 개정
MVCC 기반 시스템에서는 삭제 작업을 포함한 모든 업데이트가 문서 리비전을 생성합니다. 삭제된 리비전을 "툼스톤" 리비전이라고 합니다. 삭제된 리비전은 본질적으로 "_deleted" 속성이 true인 특수한 리비전입니다. 삭제된 리비전은 복제됩니다. 이러한 리비전은 Couchbase Lite에서 쿼리를 수행하면 반환되지 않는다는 점에서 특별합니다.

수정본 ID 구조
수정본 ID는 다음과 같은 형식입니다. "-"
- 생성 ID(새 리비전) = 생성 ID(리비전의 부모) + 1
문서가 생성될 때 가장 먼저 생성되는 수정본의 생성 ID는 1입니다.
- 콘텐츠 해시 ID = 개정 내용에서 계산된 해시
이는 동일한 콘텐츠를 가진 문서의 두 수정본이 동일한 콘텐츠 해시 ID를 갖게 된다는 의미입니다.
참고: 최적화를 위해 두 명의 작성자가 동시에 문서를 동일하게 변경하여 동일한 수정본 ID를 가진 두 개의 수정본이 수신되는 경우 Couchbase Mobile은 하나의 수정본만 저장합니다.
충돌
MVCC 기반 시스템에서는 시스템이 트리에서 분기를 만나면 충돌이 발생합니다. 리비전 트리에 대한 논의에서 트리에 두 개 이상의 리프 노드가 있는 경우라는 것을 유추할 수 있습니다.

현재 개정판
충돌이 발생하면 카우치베이스 모바일은 충돌하는 리프 노드 중에서 "승자" 또는 "현재 리비전"을 선택해야 합니다. 승자를 선택한다고 해서 충돌이 해결된 것은 아닙니다.
카우치베이스 모바일은 결정론적으로 승자를 선택합니다. 프로세스의 결정론적 특성으로 인해 카우치베이스 모바일 노드는 승자 선정에 대해 서로 통신할 필요가 없으며, 모두 다음 기준을 사용하여 동일한 승자를 선정합니다.
사례 1 : 모든 리프 수정본이 삭제 취소됨
- 가장 긴 리비전 브랜치에서 삭제되지 않은 리비전이 우승합니다.

사례 2: 모든 리프 수정본이 삭제됨
가장 긴 리비전 브랜치에서 삭제된 리프 리비전이 우승합니다.

사례 3: 일부 리프 수정본이 삭제되고 일부 수정본이 삭제되지 않음
가장 긴 리비전 브랜치에서 삭제되지 않은 리비전이 우승합니다.

사례 4: 동점인 경우
간단한 ASCII 비교에서 리비전 ID가 더 높게 정렬되는 수정본이 승자가 됩니다.

충돌 해결
누가 갈등을 처리해야 하나요?
카우치베이스 모바일은 충돌하는 개정판 중에서 현재 개정판을 선택하지만, 다음과 같은 이유로 충돌을 해결하는 것은 궁극적으로 애플리케이션의 책임입니다.
- 상충하는 개정안 중 우승자를 선택하는 것은 시스템이 우승자를 결정적으로 선택하는 데 사용하는 기준이 아닌 다른 기준에 따라 결정될 수 있습니다. 카우치베이스에서 선택한 현재 수정본이 애플리케이션에 적합한 선택이 아닐 수도 있습니다.
- 상충하는 결의안 중 명확한 승자가 없습니다. 따라서 이 경우에는 상충되는 개정판의 변경 내용을 병합해야 할 수도 있습니다. 병합의 구체적인 내용은 애플리케이션 의미론에 따라 다릅니다.
- 애플리케이션이 카우치베이스가 승자로 선택한 리비전을 사용하기로 결정하더라도 충돌하는 리비전은 여전히 데이터베이스에 남아 있다는 점을 기억하세요. 따라서 리비전 트리가 사용되지 않는 충돌하는 리비전으로 인해 너무 커지는 것을 방지하기 위해 애플리케이션은 리비전 트리에서 승자가 아닌 리비전을 삭제해야 합니다. 이에 대해서는 다음 글에서 자세히 설명하겠습니다.
충돌 처리 옵션
충돌을 처리하는 데는 두 가지 옵션이 있습니다.
옵션 1: 충돌하는 수정본 중에서 수정본 선택하기
이 옵션에서는 충돌하는 수정본 중 하나를 승자로 지정하고 나머지는 '무효화'합니다.
애플리케이션은 카우치베이스가 선택한 "현재 수정본"을 승자로 유지하거나 충돌하는 수정본 중에서 다른 수정본을 선택할 수 있습니다. 어쨌든 다음 섹션에서 설명하는 대로 데이터베이스 압축 중에 제거될 수 있도록 비승자를 삭제하는 것이 중요합니다.

옵션 2: N-방향 병합
이 옵션에서는 충돌하는 수정본의 변경 사항이 애플리케이션 의미론에 따라 병합됩니다. 병합된 변경 내용은 현재/우승 리비전이 되는 새 리비전으로 이동합니다. 이기지 못한 브랜치는 삭제됩니다.

갈등이 해결되지 않으면 어떻게 하나요?
애플리케이션이 카우치베이스 모바일에서 선택한 승자를 따르기로 결정하고 충돌을 명시적으로 해결하지 않으면 많은 수의 분기와 리프 노드가 있는 리비전 트리가 생길 수 있습니다. 이는 문서의 크기와 결과적으로 데이터베이스의 크기에 바람직하지 않은 결과를 초래합니다. 카우치베이스 모바일에는 이러한 문제를 완화하기 위한 자동 프로세스가 마련되어 있지만 궁극적으로 애플리케이션이 원치 않는 리프 리비전을 삭제할 책임이 있습니다.
다음 글에서 데이터베이스 및 리비전 트리 관리에 대한 자세한 내용을 다룰 예정이니 기대해 주세요.
다음 단계는 무엇인가요?
이 게시물은 Couchbase Mobile의 동시성 제어 시스템에 대해 소개했습니다. MVCC 기반 시스템에서 중요한 고려 사항 중 하나는 리비전 트리의 크기를 관리하고 부풀어 오르는 것을 방지하는 것입니다. 이 부분은 다음 포스트에서 다룰 예정입니다.
질문이나 피드백이 있으면 아래에 댓글을 남기거나 트위터로 언제든지 문의해 주세요. @rajagp 또는 이메일을 보내주세요. priya.rajagopal@couchbase.com. . 카우치베이스 포럼 를 통해 질문할 수 있습니다.
마지막으로 다음 분들께 감사의 말씀을 전합니다. 트라운 레이든 그리고 사친 스모트라 이 게시물에 대한 의견을 보내주셨습니다.

[...]는 카우치베이스 모바일의 충돌 해결에 대한 시리즈의 두 번째 파트입니다. 첫 번째 글인 충돌 해결 이해하기에서는 Couchbase에서 문서 수정 및 충돌이 어떻게 처리되는지 [...]에 대해 살펴보았습니다.
문서 업데이트 요청(PUT)에도 동일한 "rev가 필요함"이 적용되지만, bud API는 아직 그렇게 말하지 않습니다. 왜 그럴까요?
이 요청을 언급하고 계신가요? https://developer.couchbase.com/documentation/mobile/1.4/references/sync-gateway/rest-api/index.html?v=1.5#/document/put__db___doc_
이 경우 PUT은 문서를 만들고 업데이트하는 데 사용됩니다. 따라서 문서를 생성하는 경우 rev는 선택 사항입니다.