다음을 통해 공유


변경 내용 적용

대상 공급자에서 일괄 변경 내용을 가져오고 충돌을 처리한 후에는 대상 복제본에 변경 내용을 적용해야 합니다. 이는 일반적으로 대상 공급자의 ProcessChangeBatch(관리 코드의 경우) 또는 ProcessChangeBatch(비관리 코드의 경우) 메서드에서 수행되며, Sync Framework에서 제공하는 변경 내용 적용자 개체를 사용하면 가장 쉽게 수행할 수 있습니다.

변경 내용이 적용되는 방식

대상 공급자는 원본 공급자에서 일괄 변경 내용을 가져온 후 대상 복제본에 변경 내용을 적용합니다. Sync Framework에서 제공하는 변경 내용 적용자 개체를 가져오려면 NotifyingChangeApplier 개체(관리 코드의 경우)를 만들거나 IProviderSyncServices::CreateChangeApplier(비관리 코드의 경우)를 호출합니다. ApplyChanges(관리 코드의 경우) 또는 ApplyChanges(비관리 코드의 경우) 메서드는 충돌을 검색하고 대상 공급자의 메서드를 호출하여 대상 복제본에 변경 내용을 적용합니다.

변경 내용 항목 처리

일반적인 변경 내용 항목을 처리하는 경우 변경 내용 적용자는 우선 원본 공급자에 대해 LoadChangeData(관리 코드의 경우) 또는 ISynchronousDataRetriever::LoadChangeData(비관리 코드의 경우) 메서드를 호출하여 데이터 전송을 시작합니다. 이 메서드는 데이터 전송 메커니즘을 나타내는 object(관리 코드의 경우) 또는 IUnknown 인터페이스(비관리 코드의 경우)를 반환합니다. 그런 다음 변경 내용 적용자는 대상 공급자에 대해 SaveItemChange(관리 코드의 경우) 또는 ISynchronousNotifyingChangeApplierTarget::SaveChange(비관리 코드의 경우) 메서드를 호출하고 변경 내용 저장 컨텍스트의 일부로 데이터 전송 개체를 전달합니다. 이렇게 하면 대상 공급자에서 데이터를 대상 복제본에 전송할 수 있습니다. 데이터를 가져오거나 변경 내용을 처리할 때 발생하는 오류는 RecordRecoverableErrorForItem(관리 코드의 경우) 또는 ISaveChangeContext::SetRecoverableErrorOnChange(비관리 코드의 경우) 메서드를 통해 나타냅니다. 이 메서드는 이 항목에 대해 복구 가능한 오류를 일괄 변경 내용에 포함된 배운 정보 개체에 기록합니다. 제약 조건 충돌이 사용될 때는 RecordConstraintConflictForItem(관리 코드의 경우) 또는 ISaveChangeContext2::SetConstraintConflictOnChange(비관리 코드의 경우)를 호출하여 제약 조건 충돌을 보고합니다. 그런 다음 응용 프로그램 또는 공급자에서 지정한 대로 제약 조건 충돌이 해결됩니다.

배운 정보 업데이트

변경 내용이 적용되는 동안 변경 내용 적용자는 일괄 변경 내용에 들어 있는 배운 정보를 업데이트합니다. 배운 정보는 원본 복제본의 정보를 일괄 변경 내용의 변경 내용에 투영한 정보이며, 대상 복제본에서 일괄 변경 내용의 모든 변경 내용을 적용할 때 습득할 정보를 나타냅니다. 배운 정보는 다음과 같은 방식으로 업데이트됩니다.

  • 작업 중단이나 취소로 인해 변경 내용 중 일부만 적용된 경우 변경 내용 적용자는 투영 연산자를 사용하여 정보를 실제로 적용된 변경 내용 집합으로만 제한합니다.

  • 일부 변경 내용을 적용하지 못한 경우 변경 내용 적용자는 배운 정보에서 해당 항목을 제외합니다.

공급자 구현자는 이러한 투영, 통합 또는 제외 연산을 직접 수행할 필요가 없습니다. 이는 변경 내용 적용자가 공급자 대신 연산을 수행하기 때문입니다.

업데이트된 대상 정보 저장

업데이트된 배운 정보는 대상 복제본의 정보와 결합됩니다. 대상 공급자는 대상 복제본의 정보를 이 정보로 원자적으로 대체해야 합니다. 이러한 원자성을 구현하려면 일괄 변경 내용의 모든 변경 내용이 단일 트랜잭션으로 적용된 경우 업데이트된 정보를 일괄 변경 내용마다 한 번만 저장합니다. 변경 내용 적용자는 이를 위해 일괄 처리가 끝날 때마다 대상 공급자에 대해 StoreKnowledgeForScope(관리 코드의 경우) 또는 ISynchronousNotifyingChangeApplierTarget::SaveKnowledge(비관리 코드의 경우) 메서드를 호출합니다. 이 메서드에 전달된 정보는 대상 복제본에 적용할 업데이트된 정보입니다. 대상 공급자는 GetUpdatedDestinationKnowledge(관리 코드의 경우) 또는 ISaveChangeContext::GetKnowledgeForScope(비관리 코드의 경우) 메서드를 호출하여 업데이트된 정보를 가져올 수도 있습니다.

공급자에서 변경 단위를 사용하여 하위 항목을 나타내는 경우에는 변경 내용이 적용되는 방식이 약간 다릅니다. 자세한 내용은 변경 단위 동기화를 참조하십시오.

계층적 복제본에 대한 특수 고려 사항

계층적 복제본을 동기화할 때는 변경 내용 집합을 원본에서 대상으로 일괄 처리함에 따라 복잡한 문제가 발생할 수 있습니다. Sync Framework에서는 데이터 계층 구조의 개념을 지원하지 않습니다. 따라서 이러한 상황을 적절히 처리하는 것은 전적으로 공급자의 책임입니다.

가장 일반적인 문제는 업데이트 작업에서 부모와 자식 관계의 순서입니다. 예를 들어 다음과 같은 시나리오를 가정해 봅니다.

  1. 원본 복제본에서 새 폴더를 만들고 그 안에 새 항목 집합을 만듭니다.

  2. 대상 공급자가 원본 공급자에서 변경 내용을 요청합니다. 원본 공급자는 변경 내용 목록을 두 일괄 처리로 나누어 전송합니다. 그러나 부모 폴더 생성이 들어 있는 일괄 변경 내용은 자식 항목이 들어 있는 일괄 변경 내용보다 이후에 도착합니다.

  3. 대상 공급자는 첫 번째 일괄 처리에서 도착한 항목 집합을 저장할 위치를 결정해야 하지만 저장 위치에 대한 정보는 아직 도착하지 않은 두 번째 일괄 처리에 들어 있습니다.

계층적 업데이트 줄이기

업데이트가 발생한 경우 부모/자식 관계로 인한 복잡성을 줄이는 가장 간편한 방법은 원본 공급자에서 전역 ID를 적절히 정렬하는 것입니다. 이렇게 하면 부모 항목이 항상 자식 항목보다 먼저 도착합니다.

대상 공급자가 계층적 저장소에서 수행된 업데이트를 전송받을 때 부모/자식 관계가 잘못된 순서로 수신될 수 있습니다. 대상 공급자는 순서가 잘못된 변경 내용을 삭제하고 정보에 예외를 기록하거나 변경 내용을 큐에 저장하고 이후에 적용하는 방법으로 이러한 상황을 해결할 수 있어야 합니다. 항목의 크기가 매우 클 수도 있으므로 변경 내용을 단순히 삭제하고 정보 예외를 기록하는 방법이 가장 효율적일 수 있습니다.

계층적 삭제 줄이기

대상 공급자는 항목이 컨테이너 항목인지 여부를 확인합니다. 빈 컨테이너는 즉시 삭제할 수 있습니다. 그러나 아직 삭제 표시가 없는 항목이 컨테이너에 들어 있는 경우 공급자는 다음과 같은 방법을 선택할 수 있습니다.

  • 삭제를 큐에 저장하여 이후에 처리합니다. 컨테이너의 모든 자식이 삭제 표시되면 실제 삭제를 트리거할 수 있습니다.

  • 해당 요청을 삭제하고 정보에 예외를 설정하여 순서가 잘못된 항목이 수신되었음을 나타냅니다.

계층 구조에서 부모가 삭제된 후 자식이 추가된 시나리오를 처리하려면 큐에 저장된 삭제는 짝이 맞는 세션이 끝날 때까지만 유효해야 하고 여러 참가자 사이에 유지하지 말아야 합니다.

참고 항목

참조

ISynchronousNotifyingChangeApplier 인터페이스
ISynchronousNotifyingChangeApplierTarget::SaveKnowledge
ISynchronousDataRetriever 인터페이스
ISaveChangeContext 인터페이스
NotifyingChangeApplier
StoreKnowledgeForScope
IChangeDataRetriever
SaveChangeContext

개념

표준 사용자 지정 공급자 구현