Registrando em log e gerenciando conflitos
Durante a sincronização, um aplicativo de sincronização pode indicar que um conflito deve ser salvo em um log de conflitos, em vez de ser resolvido imediatamente. Com o uso de um log de conflitos, os conflitos podem ser resolvidos separadamente da sincronização, de forma que a sincronização pode ser concluída da forma mais eficiente possível.
Resolvendo um conflito registrando em log
Para indicar que um conflito de simultaneidade deve ser salvo, o aplicativo define uma ação de resolução de conflitos de SaveConflict (para código gerenciado) ou SRA_TRANSFER_AND_DEFER (para código não gerenciado). Para indicar que um conflito de restrição deve ser salvo, o aplicativo define uma ação de resolução de conflitos de SaveConflict (para código gerenciado) ou SCRA_TRANSFER_AND_DEFER (para código não gerenciado).
Registrando um conflito em log
Para registrar em log um conflito de simultaneidade, o aplicador de alterações chama SaveConflict (para código gerenciado) ou ISynchronousNotifyingChangeApplierTarget::SaveConflict (para código não gerenciado). Nesse método, o provedor salva os metadados da alteração conflitante, os dados da alteração conflitante e o conhecimento de conflito especificado.
Para registrar em log um conflito de restrição, o aplicador de alterações chama SaveConstraintConflict (para código gerenciado) ou ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict (para código não gerenciado). Nesse método, o provedor salva os metadados da alteração conflitante, os dados da alteração conflitante, a ID do item conflitante na réplica de destino, o motivo do conflito e o conhecimento de conflito especificado.
Para que um conflito seja armazenado no log de conflitos, o provedor deve assegurar que o conflito não seja substituído por outra alteração que já está no log de conflitos. Uma forma de realizar isso é através da criação de um conhecimento de log usando o método Combine (para código gerenciado) ou ISyncKnowledge::Union método (para código não gerenciado) a fim de combinar o conhecimento de conflito de todos os conflitos do log. Se o novo conflito estiver contido no conhecimento de log, estará obsoleto e não deverá ser adicionado ao log. Esse conhecimento de log pode ser criado sob demanda ou pode ser armazenado junto com o log de conflitos. Se o conhecimento de log estiver armazenado, ele deverá ser atualizado quando um conflito for adicionado, usando Combine (para código gerenciado) ou Union (para código não gerenciado). De forma semelhante, quando um conflito é removido, o conhecimento de log deverá ser atualizado usando Complement (para código gerenciado) ou ISyncKnowledge2::Complement (para código não gerenciado).
Removendo conflitos obsoletos
Para evitar que o log de conflitos fique grande demais, os conflitos obsoletos devem ser removidos do log de conflitos.
É mais fácil detectar e remover conflitos obsoletos usando o componente aplicador de alterações do Sync Framework. Para conectar um log de conflitos ao aplicador de alterações, o provedor ou o log de conflitos implementa as interfaces IConflictLogAccess e IConflictLogWriter (para código gerenciado) ou as interfaces IConflictLogAccess e IConflictLogWriter (para código não gerenciado). O log de conflitos é passado para o aplicador de alterações usando o
método ApplyChanges (para código gerenciado) ou o método ISynchronousNotifyingChangeApplier2::ApplyChanges (para código não gerenciado). Quando um log de conflitos é passado para o aplicador de alterações, ele detecta e remove conflitos obsoletos que estão no log no final de cada lote de alterações.
Para um log de conflitos que não se conecta a um aplicador de alterações, o próprio log de conflitos deve gerenciar os conflitos obsoletos. Um conflito pode ficar obsoleto quando é adicionado ao log de conflitos um conflito que substitui um conflito que está no log. Uma forma de detectar isso é testar a versão da alteração de cada conflito do log em relação ao conhecimento do novo conflito. Quando a versão da alteração de um conflito está contida no conhecimento do novo conflito, o conflito existente está obsoleto e deve ser removido do log. Um conflito também pode ficar obsoleto quando uma alteração é aplicada à réplica que substitui um conflito que está no log. Uma forma de detectar isso é testar a versão da alteração de cada conflito do log em relação ao conhecimento da réplica após a aplicação de cada lote de alterações. A detecção e resolução de conflitos obsoletos podem ser executadas como parte da sessão de sincronização ou em outro momento.
Resolvendo conflitos no log
Os conflitos do log de conflitos podem ser resolvidos como parte da sessão de sincronização ou em outro momento. No entanto, os conflitos do log de conflitos não devem ser resolvidos durante a aplicação de alterações, ou podem ocorrer resultados inesperados.
Quando um conflito do log for aplicado à réplica, ele deverá ser tratado como uma alteração local. Para resolver um conflito do log de conflitos, o aplicativo ou o provedor executa as seguintes etapas:
Incrementa a contagem em escala da réplica.
Atualiza a versão da alteração do item ou da unidade de alteração a fim de refletir que a alteração é feita pela réplica local com a contagem em escala atualizada.
Combina o conhecimento da réplica com o conhecimento do conflito usando Combine (para código gerenciado) ou Union (para código não gerenciado) e salva o conhecimento combinado como o novo conhecimento da réplica.
Aplica os dados de alteração à réplica.
Remove o conflito do log de conflitos.
Log de conflitos na memória
Um log de conflitos é necessário quando um provedor relata conflitos de restrição. Para ajudar um provedor que relata conflitos de restrição para uma réplica que não contém um log de conflitos, o Sync Framework fornece uma implementação das interfaces de log de conflitos que opera na memória e é usada para armazenar conflitos temporários que podem ocorrer como resultado da manipulação de conflitos de restrição. A implementação é a classe MemoryConflictLog (para código gerenciado) ou a interface IMemoryConflictLog, que pode ser obtida chamando IProviderSyncServices2::CreateMemoryConflictLog (para código não gerenciado).
A implementação do log de conflitos na memória também pode ser usada em conjunto com um log de conflitos persistente. O log de conflitos na memória pode ser usado para melhorar o desempenho, sendo usado para fornecer um cache na memória do log de conflitos total e para manipular conflitos temporários. Quando um log de conflitos persistente é encadeado ao log de conflitos na memória, os conflitos podem ser salvos no log de conflitos persistente após a conclusão da sincronização, chamando Persist (para código gerenciado) ou IMemoryConflictLog::Persist (para código não gerenciado).