Ведение журнала конфликтов и управление конфликтами
При выполнении синхронизации приложение синхронизации может указывать на необходимость сохранения конфликта в журнале конфликтов, а не на немедленное устранение конфликта. Журнал конфликтов позволяет устранять конфликты независимо от синхронизации, что обеспечивает оптимизацию производительности синхронизации.
Разрешение конфликтов с помощью ведения журнала
Чтобы указать на необходимость сохранения конфликтов параллелизма, приложение задает действие по устранению конфликта SaveConflict (для управляемого кода) или SRA_TRANSFER_AND_DEFER (для неуправляемого кода). Чтобы указать на необходимость сохранения конфликтов ограничения, приложение задает действие по устранению конфликта SaveConflict (для управляемого кода) или SCRA_TRANSFER_AND_DEFER (для неуправляемого кода).
Запись конфликта в журнал
Чтобы записать конфликт параллелизма, объект применения изменений вызывает метод SaveConflict (для управляемого кода) или ISynchronousNotifyingChangeApplierTarget::SaveConflict (для неуправляемого кода). В этом методе поставщик сохраняет метаданные конфликтующего изменения, данные конфликтующего изменения и набор знаний указанного конфликта.
Чтобы записать в журнал конфликт ограничений, объект применения изменений вызывает метод SaveConstraintConflict (для управляемого кода) или ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict (для неуправляемого кода). В этом методе поставщик сохраняет метаданные конфликтующего изменения, данные конфликтующего изменения, идентификатор конфликтующего элемента в конечной реплике, причину возникновения конфликта и набор знаний указанного конфликта.
До сохранения конфликта в журнале конфликтов поставщик должен убедиться, что конфликт не заменен другим изменением, уже зарегистрированным в журнале конфликтов. Это можно выполнить, создав набор знаний журнала с помощью метода Combine (для управляемого кода) или метода ISyncKnowledge::Union (для неуправляемого кода), чтобы объединить набор знаний всех конфликтов в журнале. Если новый конфликт содержится в наборе знаний журнала, это указывает на то, что он устарел и его не нужно добавлять к журналу. При необходимости можно создать набор знаний этого журнала по запросу или сохранить с журналом конфликтов. Если набор знаний сохранен, его необходимо обновить при добавлении конфликта с помощью метода Combine (для управляемого кода) или Union (для неуправляемого кода). Аналогично при удалении конфликта набор знаний журнала необходимо обновить с помощью метода Complement (для управляемого кода) или ISyncKnowledge2::Complement (для неуправляемого кода).
Удаление устаревших конфликтов
Чтобы ограничить размер журнала конфликтов, из него необходимо удалить устаревшие конфликты.
Устаревшие конфликты проще всего выявить и удалить с помощью компонента объекта применения изменений платформы Sync Framework. Чтобы подключить журнал конфликтов к объекту применения изменений, поставщик журнала конфликтов реализует интерфейсы IConflictLogAccess и IConflictLogWriter (для управляемого кода) или IConflictLogAccess и IConflictLogWriter (для неуправляемого кода). Журнал конфликтов передается объекту применения изменений с помощью метода
ApplyChanges (для управляемого кода) или ISynchronousNotifyingChangeApplier2::ApplyChanges (для неуправляемого кода) При передаче журнала конфликтов объекту применения изменений объект применения изменений выявляет и удаляет устаревшие конфликты, содержащиеся в журнале, в конце каждого пакета изменений.
Журнал конфликтов, не подключенный к объекту применения изменений, должен осуществлять управление устаревшими объектами самостоятельно. Конфликт может стать устаревшим при добавлении к журналу конфликта, заменяющего существующий в журнале конфликт. Одним из способов выявления такого случая является проверка версии изменения всех конфликтов в журнале по набору знаний нового конфликта. Если версия изменения конфликта содержится в наборе знаний нового конфликта, существующий конфликт является устаревшим и его необходимо удалить из журнала. Конфликт также может стать устаревшим при применении изменения к реплике, заменяющей существующий в журнале конфликт. Одним из способов выявления такого случая является проверка версии изменения всех конфликтов в журнале по набору знаний реплики после применения каждого пакета изменений. Обнаружение и устранение устаревших конфликтов можно выполнить как часть сеанса синхронизации или в другое время.
Устранение конфликтов в журнале
Конфликты в журнале конфликтов можно устранить как часть сеанса синхронизации или в другое время. Однако конфликты в журнале конфликтов не следует устранять в процессе применения изменений, поскольку это может привести к получению непредвиденных результатов.
При применении конфликта в журнале к реплике он должен обрабатываться как локальное изменение. Чтобы устранить конфликт в журнале конфликтов, приложение или поставщик выполняет следующие шаги.
Увеличивает на единицу счетчик тактов реплики.
Обновляет версию изменения элемента или базовой единицы, чтобы отразить, что изменение было выполнено локальной репликой с обновленным счетчиком тактов.
Объединяет набор знаний реплики с набором знаний конфликта с помощью метода Combine (для управляемого кода) или Union (для неуправляемого кода) и сохраняет объединенный набор знаний как новый набор знаний реплики.
Применяет к реплике информацию об изменениях.
Удаляет конфликт из журнала конфликтов.
Журнал конфликтов, расположенный в памяти
Журнал конфликтов необходим, когда поставщик сообщает о конфликте ограничения. Для поставщика, отправившего отчет о конфликте ограничения реплики и не имеющего журнала конфликтов, платформа Sync Framework обеспечивает реализацию интерфейсов журнала конфликтов, расположенного в памяти, который используется для сохранения временных конфликтов, возникающих при обработке конфликтов ограничения. Реализация содержится в классе MemoryConflictLog (для управляемого кода) или в интерфейсе IMemoryConflictLog, который можно получить вызовом метода IProviderSyncServices2::CreateMemoryConflictLog (для неуправляемого кода).
Реализация журнала конфликтов, расположенного в памяти, также может быть использована совместно с постоянным журналом конфликтов. Журнал конфликтов, расположенный в памяти, также можно использовать для повышения производительности за счет использования журнала для предоставления кэша памяти полного журнала конфликтов и для обработки временных конфликтов. При объединении в цепочку постоянного журнала конфликтов и журнала конфликтов, расположенного в памяти, после завершения синхронизации конфликты можно сохранить в постоянном журнале конфликтов путем вызова метода Persist (для управляемого кода) или IMemoryConflictLog::Persist (для неуправляемого кода).