Controlar los conflictos

Durante la sincronización, el proveedor de destino recibe un lote de cambios del proveedor de origen a través del método ProcessChangeBatch (en el código administrado) o del método ProcessChangeBatch (en el código no administrado). Entonces el proveedor de destino debe detectar y controlar cualquier conflicto que se produzca debido a esta lista.

Detección de conflictos

Hay dos categorías de conflictos que pueden producirse en la sincronización: conflictos de simultaneidad y de restricción.

Conflictos de simultaneidad

Los conflictos de simultaneidad ocurren cuando la versión de la réplica de destino no está incluida en el conocimiento de la réplica de origen. Estos conflictos se producen porque las operaciones como la actualización-eliminación y la actualización-actualización afectan al mismo elemento que se está sincronizando.

Normalmente, el proveedor de destino utiliza un objeto aplicador de cambios que Sync Framework proporciona para detectar los conflictos de simultaneidad. El aplicador de cambios se representa mediante el objeto NotifyingChangeApplier (en el código administrado) o la interfaz ISynchronousNotifyingChangeApplier (en el código no administrado). Para utilizar un aplicador de cambios con el fin de detectar los cambios, el proveedor de destino debe proporcionar información de versión para cada elemento del lote de cambios enviado por el proveedor de origen. Hay dos maneras de hacerlo:

  • El proveedor de destino genera una lista de cambios que corresponde al lote de cambios que el proveedor de origen envía. Para cada elemento del lote de cambios del proveedor de origen, el proveedor de destino agrega un elemento a su lista que contiene la versión de este elemento en la réplica de destino. Esta lista se pasa al aplicador de cambios. El aplicador de cambios la usa para comprobar que la versión de destino de cada elemento está incluida en el conocimiento de la réplica de origen.

  • El proveedor de destino no proporciona una lista de las versiones de destino al aplicador de los cambios. En su lugar, el proveedor de destino implementa el método ISynchronousNotifyingChangeApplierTarget::GetDestinationVersion (en el código administrado) o el método TryGetDestinationVersion (en el código no administrado). Este método se llamará una vez con cada elemento del lote de cambios del proveedor de origen.

Para entender mejor lo que el aplicador de cambios hace para detectar un conflicto, considere el escenario en el que un proveedor de destino recibe un lote de cambios de un proveedor de origen. Para detectar los conflictos, se siguen estos pasos para cada elemento del lote de cambios:

  1. El proveedor de destino determina si la versión de la réplica de destino del elemento está incluida en el conocimiento de la réplica de origen.

  2. Si la versión de la réplica de destino no está incluida en el conocimiento de la réplica de origen, se dice que el objeto está en conflicto.

Conflictos de restricción

Los conflictos de restricción son los que infringen las restricciones aplicadas a los elementos, como la relación de las carpetas o la ubicación de los datos con un nombre idéntico dentro de un sistema de archivos.

Dado que la detección de un conflicto de restricción depende del almacén de datos que una réplica usa, el proveedor debe detectar estos tipos de conflictos. Por ejemplo, un proveedor que representa un sistema jerárquico de archivos debe poder detectar las restricciones específicas del almacén que se aplican en los datos almacenados, como la ubicación, la denominación, el tamaño, etc.

Resolución de conflictos

Los conflictos se pueden resolver definiendo una directiva de resolución de conflictos que se aplica a todos los conflictos durante la sesión o administrando un evento que ocurre una vez por cada conflicto.

Establecer una directiva de resolución de conflictos

Para especificar una directiva que se aplicará a todos los conflictos durante una sesión, una aplicación especifica una directiva de resolución de conflictos en la propiedad ConflictResolutionPolicy del proveedor de destino (en el código administrado) o en el método ISyncSession::Start (en el código no administrado).

Establecer una acción de resolución de conflictos

Para establecer eficazmente la acción de resolución de conflictos para cada conflicto que se produce, una aplicación controla el evento de conflicto del elemento mediante ItemConflicting (en el código administrado) o ISyncCallback::OnConflict (en el código no administrado). Este evento sólo se desencadena cuando la directiva de resolución de conflictos está establecida en ApplicationDefined (en el código administrado) o en CRP_NONE (en el código no administrado).

Código administrado: cuando se genera ItemConflicting, el controlador de eventos recibe un objeto ItemConflictingEventArgs que contiene los metadatos y los datos de elemento para los dos cambios en conflicto. El controlador de eventos puede examinar los dos conflictos, realizar cambios en los metadatos o los datos de elemento, y establecer la acción para resolver el conflicto utilizando el método SetResolutionAction. A continuación, Sync Framework procesa el conflicto y realiza las llamadas adecuadas al proveedor de origen o de destino con el fin de aplicar los cambios.

Código no administrado: cuando se genera ISyncCallback::OnConflict, el controlador de eventos recibe un objeto IChangeConflict que contiene los metadatos y los datos de elemento para los dos cambios en conflicto. El controlador de eventos puede examinar los dos conflictos, realizar cambios en los metadatos o los datos de elemento, y establecer la acción para resolver el conflicto utilizando el método IChangeConflict::SetResolveActionForChange. A continuación, Sync Framework procesa el conflicto y realiza las llamadas adecuadas al proveedor de origen o de destino con el fin de aplicar los cambios.

Resoluciones de conflictos

Sync Framework proporciona el siguiente conjunto de acciones de resolución de conflictos para los que se ocupa de la mayor parte del procesamiento. Otros tipos de resolución de conflictos se pueden llevan a cabo trabajando directamente con los cambios en conflicto en el controlador de eventos de conflicto del elemento.

Resolución de conflictos Descripción ¿Está disponible como directiva de sesión o acción de elemento?

El origen gana

La réplica de origen siempre gana. Este sistema admite una solución de sincronización de sólo lectura en la que la réplica de destino no va a ser de confianza. El aplicador de cambios pasa el cambio al método SaveItemChange (en el código administrado) o al método ISynchronousNotifyingChangeApplierTarget::SaveChange (en el código no administrado). El cambio se aplica en la réplica de destino exactamente igual que cualquier cambio que no esté en conflicto.

Ambos

El destino gana

La réplica de destino siempre gana. Este sistema admite el caso en el que la réplica de destino no consume los cambios que los clientes remotos realizan. El aplicador de cambios pasa el cambio en conflicto al método ISynchronousNotifyingChangeApplierTarget::SaveChange (en el código no administrado) o al método SaveItemChange (en el código no administrado) como un cambio de una sola versión. Solo se aplica información de versión a los metadatos en la réplica de destino.

Ambos

Mezcla

Mezcla la información en un elemento en el otro. El aplicador de cambios pasa el cambio en conflicto al método SaveItemChange (en el código administrado) o al método ISynchronousNotifyingChangeApplierTarget::SaveChange (en el código no administrado) como un cambio de mezcla. Los datos de elemento de origen y los datos de elemento de destino se mezclan y el resultado se aplica a la réplica de destino.

Acción de elemento solo

Registrar

Registre el conflicto para tratarlo después y no aplique el cambio. El aplicador de cambios pasa el cambio en conflicto al método SaveConflict (en el código administrado) o al método ISynchronousNotifyingChangeApplierTarget::SaveConflict (en el código no administrado).

Acción de elemento solo

Diferir

Omita el conflicto y no aplique el cambio. El aplicador de cambios no pasa el cambio en conflicto al proveedor de destino.

Acción de elemento solo

Conflictos guardados

Cuando se registra un conflicto, se llama al método SaveConflict (en el código administrado) o al método SaveConflict (en el código no administrado) en lugar de al método SaveChange (en el código administrado) o SaveItemChange (en el código no administrado). En este caso, el proveedor debe guardar el conocimiento del conflicto, el cambio en conflicto y los datos del conflicto. Una aplicación puede enumerar a continuación estos conflictos del registro del conflicto y resolverlos posteriormente. Tenga en cuenta que este tipo de resolución de conflictos siempre supone un cambio local. Por consiguiente, la aplicación que resuelve los conflictos debe aplicar la resolución como un cambio local, actualizar el contador y agregar el conocimiento del conflicto al conocimiento local.

Además, una aplicación que esté resolviendo los conflictos guardados debe tratar los conflictos obsoletos. En particular, cuando un proveedor registra un conflicto nuevo, debe comprobarlo con respecto a su conocimiento para asegurarse de que el conflicto que se está registrando reemplaza a cualquiera de los conflictos registrados previamente para ese elemento. Los conflictos obsoletos también se deben limpiar del registro. Una aplicación puede limpiar los conflictos obsoletos de forma asincrónica en lugar de en el proveedor. En este caso, la aplicación debe comprobar que los conflictos no están obsoletos antes de intentar resolverlos.

Reducir los conflictos utilizando unidades de cambio

El número de conflictos se puede reducir utilizando unidades de cambio para representar los cambios del subelemento. Cuando se utilizan unidades de cambio, se realiza el seguimiento de las versiones en conjunto para las unidades de cambio en lugar de para el elemento. Por consiguiente, los cambios que se realizan en unidades de cambio diferentes dentro del mismo elemento no producirán un conflicto. Para obtener más información, vea Sincronizar las unidades de cambio.

Vea también

Referencia

Interfaz ISyncKnowledge
Interfaz ISyncProvider
Interfaz IKnowledgeSyncProvider
IKnowledgeSyncProvider::ProcessChangeBatch
Interfaz ISynchronousNotifyingChangeApplierTarget
Interfaz IAsynchronousNotifyingChangeApplierTarget
ISyncCallback::OnConflict
Enumeración CONFLICT_RESOLUTION_POLICY
Enumeración SYNC_RESOLVE_ACTION
SyncKnowledge
KnowledgeSyncProvider
INotifyingChangeApplierTarget
ItemConflicting
ConflictResolutionPolicy
ConflictResolutionAction

Conceptos

Proveedores de sincronización
Aplicar los cambios
Descripción del conocimiento de sincronización