Cómo la replicación de mezcla detecta y resuelve conflictos

La replicación de mezcla permite que varios nodos realicen cambios de datos autónomos, por lo que se producen situaciones en las que un cambio realizado en un nodo puede entrar en conflicto con un cambio realizado en los mismos datos en otro nodo. En otros casos, el Agente de mezcla encuentra un error, como la infracción de una restricción, y no puede propagar a otro nodo un cambio realizado en un nodo determinado. En este tema se describen los tipos de conflictos, cómo detectar y resolver los conflictos, así como los factores que influyen en la detección y resolución de los mismos.

Detectar y resolver conflictos

El Agente de mezcla detecta los conflictos mediante la columna linaje de la tabla del sistema MSmerge_contents; si se habilita el seguimiento por columna para un artículo, se utiliza también la columna COLV1. Estas columnas contienen metadatos relativos a cuándo se inserta o actualiza una fila o una columna, y acerca de qué nodos de una topología de replicación de mezcla han realizado cambios en la fila o la columna. Para ver estos metadatos, puede utilizar el procedimiento almacenado del sistema sp_showrowreplicainfo (Transact-SQL).

A medida que el Agente de mezcla enumera los cambios que deben aplicarse durante la sincronización, compara los metadatos de cada fila del publicador y del suscriptor. El Agente de mezcla utiliza estos metadatos para determinar si una fila o columna ha cambiado en más de un nodo en la topología, lo que indica un conflicto en potencia. Una vez detectado un conflicto, el Agente de mezcla inicia la resolución de conflictos especificada para el artículo y la utiliza para determinar el ganador del conflicto. La fila ganadora se aplica en el publicador y el suscriptor, y los datos de la fila perdedora se escriben en una tabla de conflictos.

El Agente de mezcla resuelve los conflictos de forma automática e inmediata, a menos que se elija la resolución interactiva de conflictos para el artículo. Para obtener más información, vea Resolución interactiva de conflictos. Si cambia manualmente la fila ganadora de un conflicto mediante el Visor de conflictos de replicación de mezcla, el Agente de mezcla aplica la versión ganadora de la fila al servidor perdedor durante la siguiente sincronización.

Registrar conflictos resueltos

Una vez que el Agente de mezcla ha resuelto el conflicto conforme a la lógica de la resolución de conflictos, registra los datos del mismo según el tipo de conflicto:

  • Para los conflictos de actualización e inserción, escribe la versión perdedora de la fila en la tabla de conflictos del artículo, que recibe un nombre con el formato conflict_<nombreDePublicación>_<nombreDeArtículo>. La información general del conflicto, como el tipo de conflicto, se escribe en la tabla MSmerge_conflicts_info.

  • Para los conflictos de eliminación, escribe la versión perdedora de la fila en la tabla MSmerge_conflicts_info. Cuando una eliminación pierde frente a una actualización, no existen datos para la fila perdedora (porque se trataba de una eliminación), por lo que no se escribe nada en conflict_<nombreDePublicación>_<nombreDeArtículo>.

Las tablas de conflictos de cada artículo se crean en la base de datos de publicaciones, en la base de datos de suscripciones o en ambas (opción predeterminada), dependiendo del valor especificado para el parámetro @conflict_logging de sp_addmergepublication. Cada tabla de conflictos tiene la misma estructura que el artículo en el que se basa, con la adición de la columna origin_datasource_id. El Agente de mezcla elimina los datos de la tabla de conflictos si superan el período de retención de conflictos para la publicación, el cual se especifica mediante el parámetro @conflict_retention de sp_addmergepublication (el valor predeterminado es 14 días).

La replicación proporciona el Visor de conflictos de replicación y los procedimientos almacenados (sp_helpmergearticleconflicts, sp_helpmergeconflictrows y sp_helpmergedeleteconflictrows) para ver los datos de los conflictos. Para obtener más información, vea Cómo ver y resolver conflictos de datos para publicaciones de mezcla (SQL Server Management Studio) y Cómo ver información de conflictos para publicaciones de mezcla (programación de la replicación con Transact-SQL).

Factores que influyen en la resolución de conflictos

Existen dos factores que influyen en la manera en que el Agente de mezcla resuelve un conflicto detectado:

  • El tipo de suscripción: cliente o servidor (que la suscripción sea una suscripción de extracción o de inserción no afecta a la solución del conflicto).

  • El tipo de seguimiento de conflictos utilizado: por filas, columnas o registros lógicos.

Tipos de suscripción

Al crear una suscripción, además de especificar si se trata de una suscripción de extracción o de inserción, es preciso indicar si es una suscripción de servidor o de cliente; una vez creada la suscripción, el tipo no se puede cambiar (en versiones anteriores de Microsoft SQL Server, las suscripciones de cliente y de servidor se denominaban suscripciones locales y globales, respectivamente).

Una suscripción a la que se ha asignado un valor de prioridad (de 0,00 a 99,99) se denomina suscripción de servidor; las suscripciones que utilizan el valor de prioridad del publicador se denominan suscripciones de cliente. Además, los suscriptores con suscripciones de servidor pueden republicar datos en otros suscriptores. En la siguiente tabla se resumen las principales diferencias y usos de cada tipo de suscriptor.

Tipo

Valor de prioridad

Uso

Servidor

Asignado por el usuario

Cuando se desea que diferentes suscriptores tengan diferentes prioridades.

Cliente

0,00, pero los cambios de datos asumen el valor de prioridad del publicador después de la sincronización

Cuando se desea que todos los suscriptores tengan la misma prioridad y que el primer suscriptor se mezcle con el publicador para ganar el conflicto.

Si se cambia una fila en una suscripción de cliente, no se asigna ninguna prioridad al cambio hasta que la suscripción se sincroniza. Durante la sincronización, a los cambios del suscriptor se les asigna la prioridad del publicador y conservan dicha prioridad para sincronizaciones posteriores. En cierto sentido, el publicador asume la propiedad del cambio. Este comportamiento permite que el primer suscriptor se sincronice con el publicador para ganar conflictos posteriores con otros suscriptores para una fila o columna determinadas.

Cuando se cambia una fila en una suscripción de servidor, la prioridad de suscripción se almacena en los metadatos del cambio. Este valor de prioridad viaja con la fila modificada cuando se mezcla con los cambios de otros suscriptores. Esto garantiza que un cambio realizado por una suscripción de prioridad superior no pierda frente a un cambio posterior realizado por una suscripción con prioridad inferior.

Una suscripción no puede tener un valor de prioridad explícito que sea superior al de su publicador. El publicador de nivel superior en una topología de replicación de mezcla tiene siempre un valor de prioridad explícito de 100,00. Todas las suscripciones a dicha publicación deben tener un valor de prioridad inferior a ese valor. En una topología de republicación:

  • Si el suscriptor va a republicar datos, la suscripción debe ser una suscripción de servidor con un valor de prioridad inferior al del publicador que se encuentra por encima del suscriptor.

  • Si el suscriptor no va a republicar datos (porque se encuentra en el nivel de hoja del árbol de republicación), la suscripción debe ser una suscripción de cliente.

Para obtener más información acerca de las suscripciones de servidor y las propiedades, vea Ejemplo de resolución de conflicto de mezcla basada en el tipo de suscripción y las prioridades asignadas.

Notificación diferida de conflictos

La notificación diferida de conflictos puede producirse con suscripciones de servidor que tienen distintas prioridades de conflicto. Imagínese una situación en la que el intercambio de cambios no conflictivos entre el publicador y un suscriptor de prioridad inferior provocan cambios conflictivos cuando un suscriptor de prioridad superior se sincroniza con el publicador.

  1. El publicador y un suscriptor de prioridad inferior, denominado LowPrioritySub, intercambian sin conflictos cambios en varias sincronizaciones.

  2. Un suscriptor de prioridad superior, denominado HighPrioritySub, no se ha sincronizado con el publicador durante algún tiempo y ha realizado cambios en las mismas filas que el suscriptor LowPrioritySub.

  3. El suscriptor HighPrioritySub se sincroniza con el publicador y gana los conflictos entre sus cambios y los del suscriptor LowPrioritySub porque tiene una prioridad superior a la del suscriptor LowPrioritySub. El publicador contiene ahora los cambios realizados por el suscriptor HighPrioritySub.

  4. El suscriptor LowPrioritySub se mezcla entonces con el publicador y descarga un gran número de cambios debido a los conflictos con el suscriptor HighPrioritySub.

Esta situación puede ser problemática si el suscriptor de prioridad inferior ha realizado cambios en las mismas filas que han perdido ahora los conflictos. Esto puede dar lugar a la pérdida de todos los cambios realizados por el suscriptor. Una posible solución a este problema es asegurarse de que todos los suscriptores tienen la misma prioridad, a menos que la lógica de negocios dicte lo contrario.

Nivel de seguimiento

El que un cambio de datos se convierta o no en un conflicto depende del tipo de seguimiento de conflictos establecido para el artículo: por filas, columnas o registros lógicos. Para obtener más información acerca del seguimiento por registros lógicos, vea Detectar y resolver conflictos en registros lógicos.

Cuando se reconocen los conflictos por filas, los cambios que se realizan en las filas correspondientes se consideran un conflicto, se realicen o no los cambios en la misma columna. Por ejemplo, suponga que se realiza un cambio en la columna de dirección de una fila del publicador y que se realiza un segundo cambio en la columna de número de teléfono de la fila correspondiente del suscriptor (en la misma tabla). Con el seguimiento de nivel de fila se detecta un conflicto porque los cambios se realizaron en la misma fila. Con el seguimiento por columnas no se detecta ningún conflicto porque los cambios se realizaron en columnas diferentes de la misma fila.

Para el seguimiento por filas y el seguimiento por columnas, la resolución del conflicto es la misma: la fila de datos completa se sobrescribe con los datos del ganador del conflicto (para el seguimiento por registros lógicos, la resolución depende de la propiedad del artículo logical_record_level_conflict_resolution).

La semántica de la aplicación determina normalmente la opción de seguimiento que se debe utilizar. Por ejemplo, si está actualizando datos de clientes que suelen incluirse al mismo tiempo, como una dirección y un número de teléfono, es recomendable elegir el seguimiento por filas. Si se eligiera el seguimiento por columnas en esta situación, los cambios realizados en la dirección del cliente en una ubicación y en el número de teléfono del cliente en otra ubicación no se detectarían como un conflicto: los datos se mezclarían en la sincronización y el error pasaría desapercibido. En otras situaciones, la actualización de columnas individuales en sitios diferentes puede ser la opción más lógica. Por ejemplo, dos sitios pueden tener acceso a diferentes tipos de información estadística sobre un cliente, como el nivel de ingresos y la cantidad total en dólares de las compras realizadas con la tarjeta de crédito. Si selecciona el seguimiento por columnas se asegurará de que ambos sitios pueden incluir datos estadísticos para diferentes columnas sin generar conflictos innecesarios.

Nota

Si la aplicación no requiere el seguimiento por columnas, es recomendable que utilice el seguimiento por filas (la opción predeterminada) porque normalmente da lugar a un mejor rendimiento de sincronización. Si se utiliza el seguimiento por filas, la tabla base puede incluir 1.024 columnas como máximo, pero es necesario filtrar las columnas desde el artículo de forma que sólo se publiquen 246 columnas como máximo. Si se utiliza el seguimiento por columnas, la tabla base puede incluir 246 columnas como máximo.

Tipos de conflictos

Aunque la mayoría de los conflictos están relacionados con actualizaciones (una actualización en un nodo entra en conflicto con una actualización o eliminación en otro nodo), existen otros tipos de conflictos. Todos los tipos de conflictos que se analizan en esta sección pueden producirse durante la fase de actualización o descarga del procesamiento de mezcla. El procesamiento de carga es la primera reconciliación de los cambios realizados en una sesión de mezcla determinada, y es la fase durante la cual el Agente de mezcla replica los cambios del suscriptor en el publicador. Los conflictos detectados durante este procesamiento se denominan conflictos de carga. El procesamiento de descarga implica mover cambios del publicador al suscriptor, y se produce después del procesamiento de carga. Los conflictos que se producen durante esta fase del procesamiento se denominan conflictos de descarga.

Para obtener más información sobre los tipos de conflicto, vea MSmerge_conflicts_info (Transact-SQL), en especial las columnas conflict_type y reason_code.

Conflictos de actualización-actualización

El Agente de mezcla detecta conflictos de actualización-actualización cuando una actualización en una fila (o columna, o registro lógico) de un nodo entra en conflicto con otra actualización en la misma fila de otro nodo. El comportamiento de la resolución predeterminada en este caso es enviar la versión ganadora de la fila al nodo perdedor y registrar la versión de la fila perdedora en la tabla de conflictos del artículo.

Conflictos de eliminación-actualización

El Agente de mezcla detecta los conflictos de eliminación-actualización cuando una actualización de los datos de un nodo entra en conflicto con una eliminación en otro. En este caso, el Agente de mezcla actualiza una fila; no obstante, cuando el Agente de mezcla busca esa fila en el destino, no la encuentra porque ha sido eliminada. Si el ganador es el nodo que actualizó la fila, la eliminación en el nodo perdedor se descarta y el Agente de mezcla envía la fila recién actualizada al perdedor del conflicto. El Agente de mezcla registra información acerca de la versión perdedora de la fila en la tabla MSmerge_conflicts_info.

Conflictos de cambio con error

El Agente de mezcla produce estos conflictos cuando no puede aplicar un cambio determinado. Esto normalmente sucede debido a una diferencia en las definiciones de restricciones entre el publicador y el suscriptor, y al uso de la propiedad NOT FOR REPLICATION (NFR) en la restricción. Los ejemplos incluyen:

  • Un conflicto de clave externa en el suscriptor, que puede producirse cuando la restricción del suscriptor no está marcada como NFR.

  • Diferencias en las restricciones entre el publicador y los suscriptores, y las mismas no están marcadas como NFR.

  • Falta de disponibilidad de objetos dependientes en el suscriptor. Por ejemplo, si publica una vista pero no la tabla de la que depende, se producirá un error al intentar realizar una inserción en el suscriptor a través de dicha vista.

  • La lógica del filtro de combinación de una publicación que no se corresponde con las restricciones de clave principal y clave externa. Los conflictos pueden producirse cuando el motor relacional de SQL Server intenta respetar una restricción pero el Agente de mezcla está respetando la definición del filtro de combinación entre los artículos. El Agente de mezcla no puede aplicar el cambio en el nodo de destino debido a las restricciones de nivel de tabla, lo que da lugar a un conflicto.

  • Pueden surgir conflictos debido a infracciones de índice único o de restricción única si se definen columnas de identidad para el artículo y no se utiliza la administración automatizada de identidades. Esto puede representar un problema si dos suscriptores utilizaran el mismo valor de identidad para una fila recién insertada. Para obtener más información acerca de la administración de intervalos de identidad, vea Replicar columnas de identidad.

  • Conflictos debidos a que la lógica del desencadenador impide que el Agente de mezcla inserte una fila en la tabla de destino. Piense en un desencadenador de actualización definido en el suscriptor; el desencadenador no está marcado como NFR e incluye la instrucción ROLLBACK en su lógica. Si se produce un error, el desencadenador emite una instrucción ROLLBACK para revertir la transacción, lo que provoca que el Agente de mezcla detecte un conflicto de cambio con error.