Compartir a través de


Detectar y resolver 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. Sync Framework proporciona objetos aplicadores de cambios que hacen más sencilla la resolución de conflictos de restricción.

El proveedor de destino detecta los conflictos de restricción durante la fase de aplicación de cambios de la sincronización. Cuando el proveedor de destino detecta un conflicto de restricción, informa sobre el conflicto al aplicador de cambios. El aplicador de cambios resuelve el conflicto según la directiva de resolución de conflictos establecida para la sesión o bien en función de la acción para la resolución del conflicto que haya establecido la aplicación para el conflicto correspondiente. A continuación, el aplicador de cambios envía todas las llamadas necesarias al proveedor de destino para que este pueda aplicar el conflicto resuelto a la réplica de destino.

Cuando un proveedor informa sobre un conflicto de restricción y utiliza un aplicador de cambios, también debe proporcionar un registro de conflictos que el aplicador de cambios utilizará para procesar y registrar los conflictos. Sync Framework proporciona una implementación en memoria de un registro de conflictos para los proveedores que no implementan su propio registro de conflictos. Para obtener más información, vea Registrar y administrar conflictos.

Tenga en cuenta que los conflictos de restricción no los puede usar un proveedor que utilice filtros personalizados o el servicio de aplicación de cambios; de lo contrario, pueden producirse resultados inesperados.

Tipos de conflictos de restricción

Los conflictos de restricción dependen del almacén de datos utilizado por la réplica de destino y, por ello, pueden ser muy diferentes. Sync Framework divide los conflictos de restricción en los tres tipos siguientes.

  • Un conflicto de colisión se produce cuando el elemento no puede guardarse porque está en conflicto con otro elemento del almacén de destino, como por ejemplo, cuando el proveedor de origen envía un archivo que tiene el mismo nombre y ubicación que un archivo que ya existe en la réplica de destino.

  • Un conflicto de elemento primario perdido se produce cuando un elemento no se puede guardar en un almacén de datos jerárquico porque requiere un elemento primario que no existe, como por ejemplo, cuando el proveedor de origen envía un archivo para que se guarde en un directorio que no existe en la réplica de destino.

  • Otros conflictos de restricción se producen cuando el elemento que se va a guardar infringe una restricción de la réplica de destino, como por ejemplo, cuando el proveedor de origen envía un archivo que es demasiado grande para guardarse en la réplica de destino o cuando el cambio infringe alguna lógica de negocio en la réplica de destino. Considérese como ejemplo de conflicto de lógica de negocio una réplica de fidelidad baja que almacene dos unidades de cambio: name y country. Considere también una réplica de fidelidad alta que almacene tres unidades de cambio: name, state/province y country. La réplica de fidelidad alta contiene una lógica de negocio que comprueba el campo state/province frente al campo country y no almacenará los cambios que no pasen la comprobación. La réplica de fidelidad baja actúa como origen y envía un elemento con country establecido en "EE. UU.". El proveedor de destino intenta aplicar el cambio a la réplica de fidelidad alta, pero en esta réplica el elemento contiene "Colombia Británica" en su campo state/province. Por consiguiente, el cambio infringe la lógica de negocio y produce un conflicto de restricción.

El proveedor de destino efectúa una selección entre los valores siguientes para especificar el motivo de un conflicto de restricción.

Motivos de aparición de conflictos de restricción Descripción

Collision (para código administrado), CCR_COLLISION (para código no administrado)

El elemento no puede guardarse porque está en conflicto con otro elemento en el almacén, como por ejemplo un elemento que tiene el mismo nombre que un elemento existente. El proveedor debe especificar el identificador del elemento de destino como identificador de elemento en conflicto.

NoParent (para código administrado), CCR_NOPARENT (para código no administrado)

El elemento no se puede guardar en el almacén de datos jerárquico porque es preciso que el elemento disponga de un elemento primario que no existe en el almacén. El proveedor puede especificar opcionalmente el identificador del elemento primario perdido como identificador de elemento en conflicto.

Other (para código administrado), CCR_OTHER (para código no administrado)

El elemento o la unidad de cambio infringe alguna otra restricción de la réplica de destino. El proveedor puede especificar opcionalmente el identificador del elemento en conflicto como identificador de elemento en conflicto.

Detectar y notificar conflictos de restricción

La detección de un conflicto de restricción depende del almacén de datos que utilice la réplica. Por ello, el proveedor de destino debe detectar los conflictos de restricción. 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.

El proveedor de destino detecta los conflictos de restricción durante la fase de aplicación de cambios de la sincronización.

Código administrado El proveedor de destino es el que detecta habitualmente los conflictos de restricción en el método SaveChangeWithChangeUnits o SaveItemChange, y se notifican llamando a RecordConstraintConflictForItem o RecordConstraintConflictForChangeUnit.

Código no administrado El proveedor de destino es el que detecta habitualmente los conflictos de restricción en el método ISynchronousNotifyingChangeApplierTarget::SaveChange o ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits, y se notifican llamando a ISaveChangeContext2::SetConstraintConflictOnChange o ISaveChangeWithChangeUnitsContext2::SetConstraintConflictOnChangeUnit.

Cuando el aplicador de cambios recibe una notificación sobre un conflicto de restricción, emprende varias medidas:

  • Cuando el conflicto de restricción es un conflicto de colisión, el aplicador de cambios determina si el conflicto es nuevo, temporal o una propagación de resolución de combinación. Durante el procesamiento del conflicto, el aplicador de cambios puede almacenar temporalmente el conflicto en el registro de conflictos si llama a SaveConstraintConflict (para código administrado) o ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict (para código no administrado). El aplicador de cambios quita los conflictos temporales del registro cuando finaliza la sesión de sincronización.

  • Resuelve los conflictos de colisión de acuerdo a la directiva de resolución de conflictos de colisión establecida para la sesión o bien de acuerdo a la acción que haya determinado la aplicación para la resolución del conflicto. Se llama a la aplicación con el fin de determinar la acción para la resolución de conflictos cuando la directiva de resolución de conflictos de colisión está establecida en ApplicationDefined (para código administrado) o CCRP_NONE (para código no administrado).

  • Resuelve los conflictos de restricción que no son de colisión según la acción de resolución de conflictos determinada por la aplicación. Una directiva de resolución de conflictos no puede establecerse para conflictos de restricción que no sean de colisión.

Resolver conflictos de restricción

El aplicador de cambios ayuda al proveedor de destino a resolver los conflictos de restricción enviando llamadas al objeto de destino del aplicador de cambios que especifica el proveedor. Cuando se especifica una directiva de resolución de conflictos de colisión, el aplicador de cambios la utiliza para determinar la acción de resolución de conflictos correcta con el fin de resolver cada conflicto de colisión que se produzca. Cuando se especifica una resolución de conflictos de colisión personalizada, el aplicador de cambios informa a la aplicación de sincronización del conflicto de colisión y la aplicación especifica la acción de resolución de conflictos. No se puede especificar una directiva de resolución de conflictos que no sean de colisión, de forma que cuando se notifica un conflicto de restricción que no sea de colisión, el aplicador de cambios avisa siempre a la aplicación para que pueda especificar la acción de resolución de conflictos. En cualquiera de los casos, el aplicador de cambios llama al método de destino del aplicador de cambios apropiado y el objeto de destino del aplicador de cambios emprende la acción, como por ejemplo guardar el cambio en la réplica o registrar el conflicto para su procesamiento ulterior.

Especificar una directiva de resolución de conflictos de colisión

Por lo general, la aplicación de sincronización determina una directiva de resolución de conflictos de colisión antes de que se inicie la sincronización.

Código administrado La aplicación determina la directiva estableciendo la propiedad CollisionConflictResolutionPolicy del proveedor de destino en el valor deseado.

Código no administrado La aplicación determina la directiva utilizando un mecanismo personalizado, como por ejemplo una interfaz personalizada que la aplicación obtiene llamando a QueryInterface en el objeto de proveedor de destino.

El proveedor de destino pasa la directiva de resolución de conflictos de colisión al método ISynchronousNotifyingChangeApplier2::ApplyChanges (para código administrado) o ApplyChanges (para código no administrado) del aplicador de cambios, de forma que este pueda enviar correctamente los métodos al destino del aplicador de cambios. El destino del aplicador de cambios se representa mediante el objeto INotifyingChangeApplierTarget2 (para código administrado) o ISynchronousNotifyingChangeApplierTarget2 (para código no administrado)

Directivas de resolución de conflictos de colisión para código administrado

Sync Framework define las directivas de resolución de conflictos de colisión siguientes para código administrado.

Directiva de resolución de conflictos Descripción

SourceWins

El cambio realizado en la réplica de origen siempre gana. Sync Framework especifica una acción de resolución de conflictos de SourceWins.

DestinationWins

El cambio realizado en la réplica de destino siempre gana. Sync Framework especifica una acción de resolución de conflictos de DestinationWins.

RenameSource

Se cambia el nombre del cambio que envió el proveedor de origen, de forma que no colisione con el elemento en conflicto en la réplica de destino, y se aplica el cambio de origen a la réplica de destino. Sync Framework especifica una acción de resolución de conflictos de RenameSource.

RenameDestination

Se cambia el elemento en conflicto en la réplica de destino, de forma que no colisione con el cambio que envió el proveedor de origen, y se aplica el cambio de origen a la réplica de destino. Sync Framework especifica una acción de resolución de conflictos de RenameDestination.

Merge

Los datos del elemento de origen se combinan con el elemento de destino. Sync Framework especifica una acción de resolución de conflictos de Merge.

ApplicationDefined

El aplicador de cambios informa a la aplicación de sincronización sobre cada conflicto de colisión a medida que se van produciendo; para ello, utiliza el evento ItemConstraint. La aplicación examina los elementos en conflicto y especifica la acción de resolución de conflictos llamando a SetResolutionAction.

Directivas de resolución de conflictos de colisión para código no administrado

Sync Framework define las directivas de resolución de conflictos de colisión siguientes para código no administrado.

Directiva de resolución de conflictos Descripción

CCRP_SOURCE_PROVIDER_WINS

El cambio realizado en la réplica de origen siempre gana. Sync Framework especifica una acción de resolución de conflictos de SCRA_ACCEPT_SOURCE_PROVIDER.

CCRP_DESTINATION_PROVIDER_WINS

El cambio realizado en la réplica de destino siempre gana. Sync Framework especifica una acción de resolución de conflictos de SCRA_ACCEPT_DESTINATION_PROVIDER.

CCRP_RENAME_SOURCE

Se cambia el nombre al cambio que envió el proveedor de origen, de forma que no colisione con el elemento en conflicto en la réplica de destino, y se aplica el cambio de origen a la réplica de destino. Sync Framework especifica una acción de resolución de conflictos de SCRA_RENAME_SOURCE.

CCRP_RENAME_DESTINATION

Se cambia el nombre al elemento en conflicto en la réplica de destino, de forma que ya no colisione con el cambio que envió el proveedor de origen, y se aplica el cambio de origen a la réplica de destino. Sync Framework especifica una acción de resolución de conflictos de SCRA_RENAME_DESTINATION.

CCRP_MERGE

Los datos del elemento de origen se combinan con el elemento de destino. Sync Framework especifica una acción de resolución de conflictos de SCRA_MERGE.

CCRP_NONE

El aplicador de cambios informa a la aplicación de sincronización sobre cada conflicto de colisión a medida que se van produciendo; para ello, utiliza el evento ISyncConstraintCallback::OnConstraintConflict. La aplicación examina los elementos en conflicto y especifica la acción de resolución de conflictos llamando a IConstraintConflict::SetConstraintResolveActionForChange o IConstraintConflict::GetConstraintResolveActionForChangeUnit.

Determinar resoluciones de conflictos personalizadas

Una aplicación puede indicar que especificará una acción de resolución de conflictos para cada conflicto de restricción que produzca. Para lograr esto, la aplicación se registra para recibir notificaciones de conflictos de restricción. Cuando se notifica un conflicto de restricción, Sync Framework avisa a la aplicación. Posteriormente, la aplicación puede analizar el conflicto y establecer la acción de resolución de conflictos que se desee.

Determinar resoluciones de conflictos personalizadas utilizando código administrado

Para recibir notificaciones acerca de conflictos de colisión, una aplicación emprende las acciones siguientes antes de iniciar la sincronización.

  • Registra un controlador de eventos para el evento ItemConstraint del proveedor de destino.

  • Establece la propiedad CollisionConflictResolutionPolicy del proveedor de destino en ApplicationDefined.

Si la aplicación ha efectuado estos pasos, el aplicador de cambios genera el evento ItemConstraint una vez para cada conflicto de restricción de colisión que se notifique durante la sincronización.

Dado que no se puede especificar una directiva de resolución de conflictos para conflictos de restricción que no sean de colisión, el aplicador de cambios también genera el evento ItemConstraint una vez para cada conflicto de restricción que no sea de colisión que se notifique.

El controlador de eventos para el evento ItemConstraint recibe un objeto ItemConstraintEventArgs que contiene los metadatos y datos de elemento para los dos cambios en conflicto. El controlador de eventos puede examinar los dos cambios en conflicto, efectuar cambios en los metadatos o datos de elemento, y establecer la acción de resolución para el conflicto mediante el uso del método SetResolutionAction. A continuación, el aplicador de cambios procesa el conflicto y envía la llamada adecuada al objeto de destino del aplicador de cambios. Tenga en cuenta que, cuando el conflicto de restricción no es una colisión, las únicas acciones de resolución de conflictos válidas son SaveConflict y SkipChange.

Sync Framework proporciona el siguiente conjunto de acciones de resolución de conflictos de restricción para las que el aplicador de cambios se ocupa de la mayor parte del procesamiento.

Acción de resolución de conflictos Descripción Válido para el tipo de conflicto

SourceWins

El cambio realizado en la réplica de origen gana. El aplicador de cambios pasa el cambio al método SaveItemChange y especifica una acción de almacenamiento de DeleteConflictingAndSaveSourceItem. El cambio de origen se aplica a la réplica de destino y el elemento de destino en conflicto se elimina en la réplica de destino.

Solo conflictos de colisión.

DestinationWins

El cambio realizado en la réplica de destino gana. El aplicador de cambios pasa el cambio de origen al método SaveItemChange y especifica una acción de almacenamiento de DeleteAndStoreTombstone. El proveedor de destino crea un marcador de exclusión para el cambio de origen. Cuando el destino actúe como el origen en una sincronización posterior, enumerará un cambio que representa la eliminación del elemento de origen y, de esta forma, lo quita de la comunidad de sincronización.

Solo conflictos de colisión.

RenameSource

Se cambia el nombre al cambio que envió el proveedor de origen, de forma que ya no se contradiga con el elemento en conflicto en la réplica de destino, y el cambio de origen se aplica a la réplica de destino. El aplicador de cambios pasa el cambio al método SaveItemChange y especifica una acción de almacenamiento de RenameSourceAndUpdateVersionAndData.

Solo conflictos de colisión.

RenameDestination

Se cambia el nombre al elemento en conflicto en la réplica de destino, de forma que ya no se contradiga con el cambio que envió el proveedor de origen, y el cambio de origen se aplica a la réplica de destino. El aplicador de cambios pasa el cambio al método SaveItemChange y especifica una acción de almacenamiento de RenameDestinationAndUpdateVersionData.

Solo conflictos de colisión.

Merge

Los datos del elemento de origen se combinan con el elemento de destino. El aplicador de cambios pasa los datos del cambio de la réplica de origen al método SaveItemChange y especifica una acción de almacenamiento de ChangeIdUpdateVersionAndMergeData. Para obtener detalles, vea Combinar elementos en conflicto, más adelante.

Solo conflictos de colisión.

SaveConflict

Registra el conflicto y no aplica el cambio. El aplicador de cambios pasa los datos del conflicto al método SaveConstraintConflict, que guarda el conflicto en un registro de conflictos. Para obtener más información sobre el registro de conflictos, vea Registrar y administrar conflictos.

Todos los conflictos de restricción.

SkipChange

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

Todos los conflictos de restricción.

Determinar resoluciones de conflictos personalizadas utilizando código no administrado

Para recibir notificaciones acerca de conflictos de colisión, una aplicación emprende las acciones siguientes antes de iniciar la sincronización.

Si la aplicación ha efectuado estos pasos, el aplicador de cambios llama al método OnConstraintConflict una vez para cada conflicto de restricción de colisión que se notifique durante la sincronización.

Dado que no se puede especificar una directiva de resolución de conflictos para conflictos de restricción que no sean de colisión, el aplicador de cambios también llama al método OnConstraintConflict una vez para cada conflicto de restricción que no sea de colisión que se notifique.

El método OnConstraintConflict recibe un objeto IConstraintConflict que contiene metadatos y datos de elemento para los dos cambios en conflicto. El método puede examinar los dos cambios en conflicto, efectuar cambios en los metadatos o datos de elemento, y establecer la acción de resolución para el conflicto mediante el uso del método IConstraintConflict::SetConstraintResolveActionForChange o IConstraintConflict::GetConstraintResolveActionForChangeUnit. A continuación, el aplicador de cambios procesa el conflicto y envía la llamada adecuada al objeto de destino del aplicador de cambios. Tenga en cuenta que, cuando el conflicto de restricción no es una colisión, las únicas acciones de resolución de conflictos válidas son SCRA_TRANSFER_AND_DEFER y SCRA_DEFER.

Sync Framework proporciona el siguiente conjunto de acciones de resolución de conflictos de restricción para las que el aplicador de cambios se ocupa de la mayor parte del procesamiento.

Directiva de resolución de conflictos Descripción Válido para el tipo de contenido

SCRA_ACCEPT_SOURCE_PROVIDER

El cambio realizado en la réplica de origen siempre gana. El aplicador de cambios pasa el cambio al método ISynchronousNotifyingChangeApplierTarget::SaveChange y especifica una acción de almacenamiento de SSA_DELETE_CONFLICTING_AND_SAVE_SOURCE_ITEM. El cambio de origen se aplica a la réplica de destino y el elemento de destino en conflicto se elimina en la réplica de destino.

Solo conflictos de colisión.

SCRA_ACCEPT_DESTINATION_PROVIDER

El cambio realizado en la réplica de destino siempre gana. El aplicador de cambios pasa el cambio de origen al método SaveChange y especifica una acción de almacenamiento de SSA_DELETE_AND_STORE_TOMBSTONE. El proveedor de destino crea un marcador de exclusión para el cambio de origen. Cuando el destino actúe como el origen en una sincronización posterior, enumerará un cambio que representa la eliminación del elemento de origen y, de esta forma, lo quita de la comunidad de sincronización.

Solo conflictos de colisión.

SCRA_RENAME_SOURCE

Se cambia el nombre al cambio que envió el proveedor de origen, de forma que ya no se contradiga con el elemento en conflicto en la réplica de destino, y el cambio de origen se aplica a la réplica de destino. El aplicador de cambios pasa el cambio al método SaveChange y especifica una acción de almacenamiento de SSA_RENAME_SOURCE_AND_UPDATE_VERSION_AND_DATA.

Solo conflictos de colisión.

SCRA_RENAME_DESTINATION

Se cambia el nombre al elemento en conflicto en la réplica de destino, de forma que ya no se contradiga con el cambio que envió el proveedor de origen, y el cambio de origen se aplica a la réplica de destino. El aplicador de cambios pasa el cambio al método SaveChange y especifica una acción de almacenamiento de SSA_RENAME_DESTINATION_AND_UPDATE_VERSION_AND_DATA.

Solo conflictos de colisión.

SCRA_MERGE

Los datos del elemento de origen se combinan con el elemento de destino. El aplicador de cambios pasa los datos del cambio de la réplica de origen al método SaveChange y especifica una acción de almacenamiento de SSA_CHANGE_ID_UPDATE_VERSION_AND_MERGE_DATA. Para obtener detalles, vea Combinar elementos en conflicto, más adelante.

Solo conflictos de colisión.

SCRA_TRANSFER_AND_DEFER

Registra el conflicto y no aplica el cambio. El aplicador de cambios pasa los datos del conflicto al método ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict, que guarda el conflicto en un registro de conflictos. Para obtener más información sobre el registro de conflictos, vea Registrar y administrar conflictos.

Todos los conflictos de restricción.

SCRA_DEFER

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

Todos los conflictos de restricción.

Combinar elementos en conflicto

La combinación de dos elementos en un conflicto de restricción de colisión es distinta a la combinación de elementos en un conflicto de simultaneidad porque los dos elementos involucrados en un conflicto de colisión tienen identificadores de elemento distintos. Por ejemplo, se crea un archivo denominado "LibrosPreferidos.txt" en una réplica y se le asigna un identificador de elemento id1. Se crea también un archivo denominado "LibrosPreferidos.txt" en una réplica y se le asigna un identificador de elemento id2. Cuando se sincronizan las réplicas, Sync Framework trata a estos dos elementos como diferentes porque sus identificadores de elemento son distintos, pero la réplica de destino los trata como un mismo elemento porque tienen el mismo nombre. De esta forma, el proveedor de destino informa de un conflicto de colisión y especifica que el contenido de los dos elementos debería estar combinado. El aplicador de cambios asigna un identificador al elemento combinado de id1 y especifica que la réplica de destino debe almacenar un marcador de exclusión de combinación para id2.

Cuando un conflicto de colisión se resuelve mediante una combinación, es necesario seleccionar uno de los identificadores de elemento como el identificador de elemento que gana, el cual está asignado al elemento combinado, y comprobar que el identificador de elemento que perdió se ha combinado. El aplicador de cambios selecciona el identificador de elemento ganador; para ello, compara los dos identificadores y selecciona el identificador más pequeño como el ganador. El identificador de elemento ganador se utiliza para identificar el elemento combinado en la réplica de destino. En la réplica de destino, se crea y almacena un marcador de exclusión de combinación. El marcador de exclusión de combinación hace un seguimiento del identificador de elemento que ha perdido para comprobar que identifica el mismo elemento como el identificador de elemento ganador en la comunidad de sincronización. Los metadatos de un marcador de exclusión de combinación son los mismos que los del marcador de exclusión del elemento eliminado, con la salvedad de que se agrega el identificador de elemento ganador.

Código administrado Cuando la acción de resolución de cambios es Merge, el aplicador de cambios llama a SaveItemChange y especifica una acción de almacenamiento de ChangeIdUpdateVersionAndMergeData. El aplicador de cambios pasa el cambio con el identificador de elemento que ha perdido como el parámetro change. Para obtener el cambio del identificador de elemento ganador, se puede llamar al método GetWinnerChange del objeto SaveChangeContext que se pasó en el parámetro context.

Código no administrado Cuando la acción de resolución de cambios es SCRA_MERGE, el aplicador de cambios llama a ISynchronousNotifyingChangeApplierTarget::SaveChange y especifica una acción de almacenamiento de SSA_CHANGE_ID_UPDATE_VERSION_AND_MERGE_DATA. El aplicador de cambios pasa el cambio con el identificador de elemento que ha perdido como el parámetro pChange. Para obtener el cambio del identificador de elemento ganador, se puede llamar al método ISaveChangeContext2::GetWinnerChange del objeto ISaveChangeContext2 que se pasó en el parámetro pSaveContext.

El proveedor de destino debe seguir varios pasos para procesar la acción de combinación correctamente. Considere una acción de combinación que especifica id1 como el identificador de elemento que ha perdido y id2 como el identificador de elemento ganador. El proveedor de destino debe seguir estos pasos en una transacción.

  1. Un marcador de exclusión de combinación se almacena en los metadatos de destino. El marcador de exclusión de combinación contiene id1 como el identificador de elemento que ha perdido y id2 como el identificador de elemento ganador. Si un marcador de exclusión de combinación ya existe en la réplica de destino que contiene id1 como el identificador de elemento que ha perdido y otro identificador de elemento, id3, como el identificador de elemento ganador, el proveedor sigue estos pasos.

    1. Si id2 es mayor que id3, el proveedor crea y almacena dos marcadores de exclusión de combinación. Un marcador de exclusión de combinación contiene id1 como el identificador de elemento que ha perdido y id2 como el identificador de elemento ganador. El otro marcador de exclusión de combinación contiene id2 como el identificador de elemento que ha perdido e id3 como el identificador de elemento ganador. Es posible que este segundo marcador de exclusión de combinación ya exista, en cuyo caso se le deja tal cual. De esta manera, se crea una cadena de marcadores de exclusión de combinación, en orden descendente según identificadores de elemento.

    2. Si id3 es mayor que id2, el proveedor devuelve un error.

  2. Combina los datos para el elemento en la réplica de destino con los datos para el elemento del proveedor de origen. id1 o id2 pueden identificar al elemento de destino.

  3. Aplica los metadatos para el cambio a los metadatos de destino y los datos combinados para el cambio al almacén de elementos de destino, utilizando el identificador de elemento ganador, id2, como el identificador de elemento para el cambio combinado. Los metadatos para el cambio se pueden obtener llamando al método GetWinnerChange de context (para código administrado) o al método GetWinnerChange de pContext (para código no administrado).

Propagar un elemento combinado

La propagación de elementos combinados a partir de un conflicto de restricción de colisión es distinta a la propagación de elementos combinados a partir de un conflicto de simultaneidad porque los conflictos pueden producirse con el identificador de elemento ganador, con el identificador de elemento que ha perdido o con ambos. Por ejemplo, la réplica X contiene un elemento con un identificador id1 que se combinó a partir de elementos con los identificadores id1 y id2. La réplica Y contiene un elemento con un identificador id2 y ha realizado cambios locales en el elemento. Cuando el elemento combinado identificado por id1 se envía desde la réplica X a la réplica Y, se produce un conflicto porque id1 se refiere al mismo elemento que id2.

El aplicador de cambios ayuda al proveedor de destino a aplicar un cambio de elemento combinado mediante la detección de conflictos de simultaneidad que se producen con el identificador de elemento ganador y con el identificador de elemento que ha perdido, así como mediante la determinación de las acciones adecuadas que debe emprender el proveedor de destino para aplicar el cambio de elemento combinado a la réplica de destino. Si el proveedor de destino detecta un conflicto de restricción cuando aplica un cambio de elemento combinado, debe notificar el conflicto de restricción del mismo modo que cualquier otro conflicto de restricción.

El aplicador de cambios también detecta cuando la réplica de origen y la réplica de destino discrepan sobre la identidad de un elemento. Por ejemplo, la réplica X resuelve un conflicto de colisión entre los elementos con identificadores id1 e id2, para lo cual combina los elementos y asigna id1 al elemento combinado. La réplica Y resuelve un conflicto de colisión entre los elementos con identificadores id1 e id2, para ello, cambia el nombre del elemento que identifica id1 y conserva ambos elementos. La réplica X envía el elemento combinado que identifica id1 y un marcador de exclusión de combinación que indica que id2 se ha combinado en id1. Se detecta el conflicto en id1 y se resuelve como un conflicto de simultaneidad. Se detecta el conflicto en id2 y se notifica a la aplicación de sincronización como un conflicto de identidad, para lo cual se especifica un motivo de conflicto de Identity (para código administrado) o CCR_IDENTITY (para código no administrado). La aplicación determina si se ha de resolver el conflicto conservando el cambio de origen o el cambio de destino.

Tenga en cuenta que, cuando el proveedor de origen usa el filtrado de unidades de cambio y el proveedor de destino no se filtra, puede producirse a veces un conflicto de identidad aunque el elemento identificado por el marcador de exclusión de combinación vaya a quitarse de la réplica de destino. Esto se produce por la forma en que el aplicador de cambios controla el conocimiento filtrado. Para garantizar una sincronización y propagación correctas del marcador de exclusión de combinación, el proveedor de destino debe conservar el marcador de exclusión de combinación y quitar el elemento en conflicto de la réplica de destino.

Cuando el proveedor de origen envía un cambio de elemento combinado, el aplicador de cambios determina las acciones adecuadas que debe emprender el proveedor de destino para aplicar el cambio en la réplica de destino. La tabla siguiente enumera las acciones de almacenamiento que puede especificar el aplicador de cambios y las acciones que debe emprender el proveedor para aplicar el cambio.

Acción de almacenamiento Acciones del proveedor

ChangeIdUpdateVersionAndSaveData (para código administrado), SSA_CHANGE_ID_UPDATE_VERSION_AND_SAVE_DATA (para código no administrado)

Almacene un marcador de exclusión de combinación para el identificador de elemento que ha perdido; para ello, siga los mismos pasos que se describieron en Combinar elementos en conflicto anteriormente. Aplique el cambio de elemento ganador.

ChangeIdUpdateVersionOnly (para código administrado), SSA_CHANGE_ID_UPDATE_VERSION_ONLY (para código no administrado)

Almacene un marcador de exclusión de combinación para el identificador de elemento que ha perdido; para ello, siga los mismos pasos que se describieron en Combinar elementos en conflicto anteriormente. Aplique solamente los metadatos para el cambio de elemento ganador.

ChangeIdUpdateVersionAndDeleteAndStoreTombstone (para código administrado), SSA_CHANGE_ID_UPDATE_VERSION_AND_DELETE_AND_STORE_TOMBSTONE (para código no administrado)

Almacene un marcador de exclusión de combinación para el identificador de elemento que ha perdido; para ello, siga los mismos pasos que se describieron en Combinar elementos en conflicto anteriormente. Elimine el elemento que identifica el identificador de elemento ganador y guarde un marcador de exclusión para él.

StoreMergeTombstone (para código administrado), SSA_STORE_MERGE_TOMBSTONE (para código no administrado)

Almacene un marcador de exclusión de combinación para el identificador de elemento que ha perdido; para ello, siga los mismos pasos que se describieron en Combinar elementos en conflicto anteriormente.

Nota

Todos los pasos en una acción de almacenamiento deben aplicarse como una acción atómica.

Vea también

Referencia

Interfaz ISaveChangeContext2
Interfaz ISaveChangeWithChangeUnitsContext2
Interfaz ISynchronousNotifyingChangeApplier2
Interfaz ISynchronousNotifyingChangeApplierTarget2
SaveChangeContext
SaveChangeWithChangeUnitsContext
NotifyingChangeApplier
INotifyingChangeApplierTarget2

Conceptos

Controlar los conflictos
Detectar y resolver conflictos de simultaneidad