Aprovisionar una base de datos servidor para la sincronización de colaboración (no SQL Server)

Nota

La finalidad de los temas de esta sección de la documentación, Sincronizar otras bases de datos compatibles con ADO.NET, es mostrar cómo se pueden sincronizar otras bases de datos distintas de SQL Server mediante Sync Framework. En esta versión, se utiliza SQL Server en los ejemplos de código, pero el código puede utilizarse en otras bases de datos compatibles con ADO.NET, siempre y cuando se modifiquen los objetos específicos de SQL Server (como SqlConnection) y las consultas SQL que se muestran. Para obtener información acerca de la sincronización de SQL Server, vea Configurar y ejecutar la sincronización de colaboración (SQL Server).

En este tema se describe cómo se aprovisiona una base de datos sincronizada mediante DbSyncProvider para poder realizar el seguimiento de los cambios incrementales de dicha base de datos. Este seguimiento de los cambios se lleva a cabo para que dichos cambios puedan aplicarse en otros nodos durante una sesión de sincronización. Para aprovisionar una base de datos para Sync Framework, siga estos pasos:

  1. Habilite el aislamiento de instantánea en la base de datos

  2. Identifique las tablas que se van a sincronizar

  3. Cree tablas de seguimiento para almacenar los metadatos por tabla y cree los índices de esas tablas

  4. Cree los desencadenadores de cada tabla base para rellenar y actualizar las tablas de seguimiento

  5. (Opcional) Administre los datos existentes de la base de datos

  6. Cree una tabla de seguimiento para almacenar el metadatos por ámbito y cree un índice de esta tabla

  7. Defina los ámbitos que se van a sincronizar, lo que indica qué tablas se sincronizan como una unidad

  8. Cree procedimientos almacenados para seleccionar y actualizar datos y metadatos

Estos pasos no son necesarios en bases de datos sincronizadas mediante SqlCeSyncProvider; el aprovisionamiento se administra en Sync Framework cuando se inicializa la base de datos.

Una vez que se aprovisiona una base de datos, se puede sincronizar con otros nodos. Para obtener más información acerca de cómo configurar y ejecutar la sincronización, vea Configurar y ejecutar la sincronización de colaboración (no SQL Server).

Habilitar el aislamiento de instantánea en la base de datos

Durante la fase de enumeración de cambios de una sesión de sincronización, Sync Framework inicia transacciones con aislamiento de instantánea. Para iniciar transacciones con aislamiento de instantánea, debe establecer la opción de base de datos ALLOW_SNAPSHOT_ISOLATION en ON, tal y como se muestra en el ejemplo de código siguiente:

ALTER DATABASE [database name] SET ALLOW_SNAPSHOT_ISOLATION ON

Para obtener más información, vea los Libros en pantalla de SQL Server.

Identificar las tablas que se van a sincronizar

El primer paso en el proceso de aprovisionamiento de la base de datos consiste en identificar las tablas que se van a sincronizar. Cada tabla debe tener una clave principal. Considere el ejemplo de código siguiente. Muestra el esquema de la tabla Sales.Customer de la base de datos SyncSamplesDb_Peer1.

CREATE TABLE Sales.Customer(
    CustomerId uniqueidentifier NOT NULL PRIMARY KEY DEFAULT NEWID(), 
    CustomerName nvarchar(100) NOT NULL,
    SalesPerson nvarchar(100) NOT NULL,
    CustomerType nvarchar(100) NOT NULL)

Cada una de las tablas que se sincronizan tiene un objeto DbSyncAdapter asociado y especifica la clave principal de la colección RowIdColumns de ese objeto. Para obtener más información, vea Configurar y ejecutar la sincronización de colaboración (no SQL Server).

Las tablas pueden estar vacías o pueden contener datos. Si la tabla contiene filas de datos que hay que sincronizar, debe asegurarse de que cada fila tiene una entrada de metadatos en la tabla de seguimiento de cambios adecuada. Para obtener más información, vea Administrar los datos existentes de la base de datos.

Crear tablas de seguimiento para metadatos por tabla

Sync Framework necesita un mecanismo para hacer un seguimiento de las filas que se han modificado desde la sesión de sincronización anterior entre dos nodos. Los cambios se representan mediante dos tipos diferentes de metadatos:

  • Los metadatos por tabla, que realizan el seguimiento de las inserciones, actualizaciones y eliminaciones de cada una de las tablas que se sincronizan.

  • Los metadatos por ámbito, que realizan el seguimiento de los cambios que cada nodo recibe de otros nodos.

El seguimiento de los metadatos por tabla se lleva a cabo utilizando una tabla de seguimiento por cada tabla base. Las tablas de seguimiento y la tabla base deben encontrarse en cada una de las bases de datos sincronizadas mediante DbSyncProvider. La clave principal de la tabla de seguimiento es la misma que en la tabla base y las columnas adicionales son necesarias. Estas columnas se describen en la tabla siguiente. Los nombres de las columnas adicionales no tienen que ser iguales que las que se muestran, pero el orden y el tipo deben coincidir con las consultas o los procedimientos que tienen acceso a las tablas de seguimiento. Algunos de estos procedimientos se tratan en Crear procedimientos almacenados para seleccionar y actualizar datos y metadatos.

Columna Descripción Se actualiza cuando...…

<Clave principal (PK) de la tabla base>: contiene una columna para cada columna de clave principal.

Columnas de clave principal de la tabla base.

Se inserta una fila en la tabla base. Esta inserción pudo originarse en el nodo local o remoto.

update_scope_local_id

Identificador del ámbito en que se realizó la última actualización o eliminación. En las actualizaciones o eliminaciones que se originan en el nodo local, esta columna es NULL.

Hace referencia a la columna scope_local_id de la tabla de información del ámbito. Para obtener más información, vea "Crear tablas de seguimiento para metadatos por ámbito".

Se aplica a la tabla base una actualización o eliminación de un nodo remoto.

scope_update_peer_key

Identidad del nodo en que se realizó la última actualización o eliminación.

Se aplica a la tabla base una actualización o eliminación de un nodo remoto.

scope_update_peer_timestamp

Valor de marca de tiempo de la base de datos remota durante la actualización o eliminación original de la fila.

Se aplica a la tabla base una actualización o eliminación de un nodo remoto.

local_update_peer_key

Identidad del nodo local. Esta columna contendrá el valor 0 en cada fila a menos que la base de datos local se restaure a partir de una copia de seguridad. 1

Se aplica a la tabla base una actualización o eliminación de una operación local o de un nodo remoto.

local_update_peer_timestamp

Valor de marca de tiempo de la base de datos local durante la actualización o eliminación de la fila en la base de datos local. 1

Se aplica a la tabla base una actualización o eliminación de una operación local o de un nodo remoto.

create_scope_local_id

Identidad del ámbito en que se realizó la inserción. En las actualizaciones o eliminaciones que se originan en el nodo local, esta columna es NULL.

Hace referencia a la columna scope_local_id de la tabla de información del ámbito. Para obtener más información, vea "Crear tablas de seguimiento para metadatos por ámbito" en Aprovisionar una base de datos servidor para la sincronización de colaboración (no SQL Server).

Se aplica a la tabla base una inserción de un nodo remoto.

scope_create_peer_key

Identidad del nodo en que se realizó la inserción.

Se aplica a la tabla base una inserción de un nodo remoto.

scope_create_peer_timestamp

Valor de marca de tiempo de la base de datos remota durante la inserción original de la fila.

Se aplica a la tabla base una inserción de un nodo remoto.

local_create_peer_key

Identidad del nodo local. Esta columna contendrá el valor 0 en cada fila a menos que la base de datos local se restaure a partir de una copia de seguridad. 1

Se aplica a la tabla base una inserción de una operación local o de un nodo remoto.

local_create_peer_timestamp

Valor de marca de tiempo de la base de datos local cuando la fila se insertó en la base de datos local. 1

Se aplica a la tabla base una inserción de una operación local o de un nodo remoto.

sync_row_is_tombstone

El valor 1 indica que una entrada de los metadatos corresponde a una eliminación en la tabla base.

Se elimina una fila de la tabla base. Esta eliminación pudo originarse en el nodo local o remoto.

last_change_datetime

Fecha y hora en que la fila de los metadatos se actualizó por última vez.

Se inserta o actualiza una fila en esta tabla de seguimiento.

restore_timestamp

Almacena el valor de local_update_peer_timestamp en el momento de la restauración de una base de datos. El valor se utiliza posteriormente como valor de la marca de tiempo de la actualización local.

Normalmente tiene el valor NULL, aunque el proceso de restauración puede establecerlo en otro valor. Se establece en NULL siempre que se actualiza una fila.

<Columnas de filtro> - agregue una columna para cada columna que no sea de clave principal que se utilice en la cláusula WHERE de filtro de cualquier ámbito.

Solo es necesaria si la tabla se filtra para uno o varios ámbitos. Almacena el valor de las columnas filtradas por inserciones, actualizaciones y eliminaciones.

Se inserta, actualiza o elimina una fila de la tabla base. Esta eliminación pudo originarse en el nodo local o remoto.

1 Se utiliza en Sync Framework cuando se sincronizan ámbitos superpuestos. Observe en el ejemplo siguiente las actualizaciones de una base de datos que sincroniza el ámbito X con el cliente A y el ámbito Y con el cliente B. Los dos ámbitos contienen la fila Q.

  1. La fila Q se actualiza en el cliente A y, a continuación, se sincroniza con la base de datos.

  2. El cliente B se sincroniza con la base de datos y recibe la actualización de la fila Q.

    El cliente B no tiene en cuenta el ámbito X, de modo que el cambio del cliente A debe aparecer como si se originara en la base de datos. Para conseguir esto, deben utilizarse los valores de local_update_peer_key y local_update_peer_timestamp cuando se sincroniza con el cliente B o cualquier otro cliente que no sincroniza el ámbito almacenado en update_scope_local_id en la fila Q.

  3. La fila Q se actualiza en la base de datos y, a continuación, se sincroniza con el cliente A.

    El cliente A tiene en cuenta el ámbito X, de modo que los valores de scope_update_peer_key y scope_update_peer_timestamp se utilizan cuando se sincroniza con el cliente A o con cualquier otro cliente que se sincronice con el ámbito X.

Le recomendamos que cree un esquema de la base de datos diferente para la tabla de seguimiento y para todos los demás objetos relacionados con los metadatos de sincronización. Esto le ayudará a aislar los metadatos de los datos en las tablas base. Para obtener un rendimiento óptimo, cree los índices de cada tabla de seguimiento:

  • Si los datos no están filtrados, utilice la misma clave principal que la tabla base y cree un índice no clúster en (local_update_peer_timestamp)

  • Si los datos están filtrados, utilice la misma clave principal que la tabla base y cree un índice no clúster en (local_update_peer_timestamp, <columnas de filtro>, <columnas de clave principal>)

En los ejemplos de código siguientes se crea una tabla en el esquema Sync que hace un seguimiento de los cambios de la tabla Sales.Customer y se agrega un índice a la tabla.

 CREATE TABLE Sync.Customer_Tracking(
     
     CustomerId uniqueidentifier NOT NULL PRIMARY KEY,          
     
     update_scope_local_id int NULL, 
     scope_update_peer_key int,
     scope_update_peer_timestamp bigint,
     local_update_peer_key int,
     local_update_peer_timestamp timestamp,
 
     create_scope_local_id int NULL,
     scope_create_peer_key int,
     scope_create_peer_timestamp bigint,
     local_create_peer_key int,
     local_create_peer_timestamp bigint,
 
     sync_row_is_tombstone int, 
     restore_timestamp bigint, 
     last_change_datetime datetime default NULL)
 CREATE NONCLUSTERED INDEX NonClustered_Customer_Tracking
 ON Sync.Customer_Tracking ([local_update_peer_timestamp])

Crear desencadenadores para rellenar y actualizar las tablas de seguimiento

Después de crear las tablas de seguimiento, agregue un desencadenador INSERT, UPDATE y DELETE a cada tabla base. Cuando un usuario o Sync Framework inserta, actualiza o elimina una fila de una tabla base, se activa un desencadenador y los metadatos de esa fila se insertan o actualizan en la tabla de seguimiento de cambios. Si Sync Framework aplicó el cambio a la tabla base (porque procedía de otro nodo), Sync Framework actualiza la tabla de seguimiento de cambios para reflejar el origen del cambio.

El ejemplo de código siguiente crea un desencadenador que actualiza los metadatos de seguimiento de cambios en la tabla Sales.Customer_Tracking cuando se realiza una actualización en la tabla Sales.Customer. Para ver ejemplos de desencadenadores de inserción y eliminación, vea Scripts de configuración para los temas de procedimientos del proveedor de base de datos.

CREATE TRIGGER Customer_UpdateTrigger ON Sales.Customer FOR UPDATE
AS    
    UPDATE t    
    SET 
        update_scope_local_id = NULL, local_update_peer_key = 0, 
        restore_timestamp = NULL, last_change_datetime = GetDate() 
    FROM Sync.Customer_Tracking t JOIN inserted i ON t.[CustomerId] = i.[CustomerId]        

Administrar los datos existentes de la base de datos

Los desencadenadores de la tabla base insertan y actualizan los metadatos de seguimiento de cambios de cada tabla. Por tanto, las tablas de seguimiento de cambios no contienen información sobre las filas que se insertaron en una tabla base antes de que se agregaran los desencadenadores. Para administrar los datos existentes de la base de datos, deben insertarse metadatos de los mismos. A continuación, durante la primera sesión de sincronización, todas las filas se envían como nuevas inserciones a la base de datos de destino. En el ejemplo de código siguiente se muestra el comando que se ejecuta en cada tabla base cuando se han agregado los desencadenadores a la tabla base:

INSERT INTO [tracking table] ([pk columns], create_scope_local_id, local_create_peer_key, local_create_peer_timestamp, update_scope_local_id, local_update_peer_key, restore_timestamp, sync_row_is_tombstone)
SELECT [pk columns], NULL, 0, @@DBTS+1, NULL, 0, NULL, 0 from [base table] baseT left outer join [tracking table] trackingT
On baseT.[pk columns]=trackingT.[pk columns]
where tracking.[pk columns] is null

Crear tablas de seguimiento para metadatos por ámbito

El seguimiento de los metadatos por ámbito normalmente se lleva a cabo utilizado dos tablas de cada base de datos:

  • En la tabla de información de ámbito se almacena el conocimiento de sincronización de cada ámbito en formato binario. Un ámbito es una agrupación lógica de tablas que define qué datos deberían sincronizarse como una unidad.

  • En la tabla de asignación de ámbitos se identifican las tablas de una base de datos que pertenecen a un ámbito determinado. Es posible que una tabla pertenezca a varios ámbitos. La tabla de asignación debe contener una entrada para cada par <ámbito, tabla>.

Sync Framework utiliza este conocimiento para determinar los cambios que se van a enviar a cada base de datos durante la sincronización. Las aplicaciones no tienen que trabajar directamente con el conocimiento. Considere una topología de sincronización bidireccional con tres nodos:

  1. Nodo1 y Nodo2 sincronizan todos los cambios.

  2. Nodo1 se sincroniza con Nodo3.

  3. Un usuario realiza una actualización en Nodo2.

  4. Nodo3 se sincroniza con Nodo2.

Cuando Nodo3 se sincroniza con Nodo2, Nodo3 ya tiene la mayoría de los cambios de Nodo2, pues Nodo3 se sincronizó primero con Nodo1. El conocimiento permite que Sync Framework reconozca esta situación y sincronice exclusivamente la actualización que se produjo en Nodo2. Para obtener más información acerca del conocimiento, vea Descripción del conocimiento de sincronización.

En la tabla siguiente se describen las columnas de la tabla de información del ámbito.

Columna Descripción Se actualiza cuando...…

scope_id

Identificador del ámbito, normalmente se trata de un GUID.

Nunca se actualiza

scope_local_id

Identificador entero del ámbito. Debería ser una columna IDENTITY.

Nunca se actualiza

scope_name

Nombre del ámbito.

Nunca se actualiza

scope_sync_knowledge

Representación binaria del conocimiento de sincronización de cada ámbito.

Se han aplicado todos los cambios en un destino durante una sesión de sincronización.

scope_tombstone_cleanup_knowledge

Representación binaria del conocimiento olvidado de cada ámbito. El conocimiento olvidado se utiliza en los metadatos que se han limpiado.

Se han aplicado todos los cambios en un destino durante una sesión de sincronización.

scope_timestamp

Valor de marca de tiempo durante la última actualización de la fila de los metadatos.

Se actualiza una fila de esta tabla de seguimiento.

scope_cleanup_timestamp

Valor de marca de tiempo durante la limpieza del marcador de exclusión más reciente que se realizó en este ámbito.

Los marcadores de exclusión se limpian en otro ámbito que tiene tablas superpuestas.

En el ejemplo de código siguiente se crea una tabla de información del ámbito.

CREATE TABLE Sync.ScopeInfo(       
    scope_local_id int IDENTITY(1,1),
    scope_id uniqueidentifier default NEWID(),
    scope_name nvarchar(100) NOT NULL PRIMARY KEY,
    scope_sync_knowledge varbinary(max) NULL,
    scope_tombstone_cleanup_knowledge varbinary(max) NULL,
    scope_timestamp timestamp,
    scope_cleanup_timestamp bigint)

La tabla de información del ámbito se consulta casi siempre para recuperar información sobre un ámbito determinado, en función del nombre del ámbito. Por consiguiente, la clave principal se define en la columna scope_name.

En la tabla siguiente se describen las columnas de la tabla de asignación de ámbitos.

Columna Descripción Se actualiza cuando...…

table_name

Nombre de la tabla.

Nunca se actualiza

scope_name

Nombre del ámbito.

Nunca se actualiza

En los ejemplos de código siguientes se crea una tabla de asignación de ámbitos y un índice de esa tabla.

CREATE TABLE Sync.ScopeTableMap(       
    scope_name nvarchar(100) ,
    table_name nvarchar(100)     
    )
CREATE UNIQUE CLUSTERED INDEX Clustered_ScopeTableMap ON Sync.ScopeTableMap(scope_name, table_name)

Definir los ámbitos que se van a sincronizar

Después de crear las tablas de ámbito, elija uno o varios ámbitos para sincronizarlos. Por ejemplo, puede definir un ámbito denominado Sales e incluir las tablas Customer, CustomerContact, OrderHeader y OrderDetail en ese ámbito. Cuando se sincroniza el ámbito Sales, los cambios realizados a las cuatro tablas se intercambian entre los dos nodos. La definición de un ámbito es un proceso que consta de dos partes:

  1. La adición de entradas a la tabla de información del ámbito y la tabla de asignación del ámbito, como en el ejemplo de código siguiente.

    INSERT INTO Sync.ScopeInfo(scope_name) VALUES (''Sales'')
    INSERT INTO Sync.ScopeTableMap(scope_name, table_name) VALUES (''Sales'', ''Sales.Customer'')
    INSERT INTO Sync.ScopeTableMap(scope_name, table_name) VALUES (''Sales'', ''Sales.CustomerContact'')
    
  2. La especificación del nombre del ámbito en la propiedad ScopeName del objeto DbSyncProvider y la adición de un objeto DbSyncAdapter en cada una de las tablas que se pretende incluir en el ámbito. Para obtener más información, vea "Código de la aplicación para ScopeName y Connection" en Configurar y ejecutar la sincronización de colaboración (no SQL Server).

Importante

Una vez que un ámbito se ha sincronizado por primera vez, no debería cambiarse. Si se cambian las tablas del ámbito o las cláusulas de filtro de esas tablas, puede producirse una falta de convergencia de los datos.

Ámbitos filtrados y superpuestos

Un ámbito se filtra si solo un subconjunto de las filas de la tabla base están incluido en el ámbito. Por ejemplo, puede definir un ámbito filtrado denominado sales-WA que contenga únicamente los datos de ventas del estado de Washington. Para filtrar los datos, la consulta o procedimiento que especifique para la propiedad SelectIncrementalChangesCommand del objeto DbSyncAdapter deberá incluir una cláusula WHERE que seleccione los datos adecuados. La consulta o procedimiento deberían seleccionar cambios basados en las columnas de filtro en la tabla de seguimiento en lugar de en las columnas de filtro de la tabla base.

No se admiten los tipos de filtrado siguientes:

  • Filtrado de columnas: todas las columnas deben incluirse en las consultas o procedimientos que seleccionan y aplican cambios.

  • Actualizaciones en columnas que se utilizan en el filtrado: si un usuario actualiza un valor en una columna que se utiliza para el filtrado, una fila se mueve de un ámbito a otro. La fila se envía al nuevo ámbito al que ahora pertenece, pero no se elimina del anterior.

Dos ámbitos se superponen si comparten datos comunes entre ellos. Por ejemplo, la tabla products podría estar incluida en un ámbito sales y un ámbito inventory. Estos dos ámbitos pueden estar superpuestos y filtrados. En los escenarios siguientes se muestran los modos en que pueden producirse las operaciones de filtrado y solapamiento:

  • Escenario 1:

    • El ámbito 1 es sales-WA. Este ámbito incluye: products; orders, con un filtro de state=WA, y order_details, con un filtro de state=WA.

    • El ámbito 2 es sales-OR. Este ámbito incluye: products; orders, con un filtro de state=OR, y order_details, con un filtro de state=OR.

    En este escenario, los dos ámbitos comparten la tabla products completa. Las tablas orders y order_details están en los dos ámbitos, pero los filtros no se superponen; por tanto, los ámbitos no comparten filas de estas tablas.

  • Escenario 2:

    • El ámbito 1 es sales-WA. Este ámbito incluye: products; orders, con un filtro de state=WA, y order_details, con un filtro de state=WA.

    • El ámbito 2 es sales-Northwest. Este ámbito incluye: products; orders, con un filtro de state=WA OR state=ID, y shippers.

    En este escenario, los dos ámbitos comparten de nuevo la tabla products completa. La tabla orders está en los dos ámbitos y los filtros se superponen; los dos ámbitos comparten, por tanto, las filas que satisfacen el filtro state=WA. Las tablas shippers y order_details no se comparten entre los ámbitos.

Hay muchas maneras diferentes en las que se pueden definir los ámbitos, pero debe seguirse este principio: todos los datos que se sincronicen entre un par de bases de datos en la topología de sincronización pueden pertenecer exclusivamente a un único ámbito. Por ejemplo, en el escenario 2 anterior, la base de datos A y la base de datos B podrían sincronizar el ámbito 1, mientras que la base de datos A y la base de datos C podrían sincronizar el ámbito 2. La base de datos A y la base de datos B no podrían sincronizar el ámbito 2 porque las filas de products y orders pertenecen a los dos ámbitos.

Crear procedimientos almacenados para seleccionar y actualizar datos y metadatos

Después de crear las tablas de metadatos, cree consultas o procedimientos almacenados de SQL (se recomienda) para seleccionar y aplicar los cambios a las tablas base y las tablas de metadatos. Los procedimientos almacenados se recomiendan por motivos de rendimiento y seguridad. Estas consultas o procedimientos se especifican para los comandos de DbSyncAdapter siguientes. Estos comandos se describen en "Adaptador de sincronización", en Configurar y ejecutar la sincronización de colaboración (no SQL Server).

Los ejemplos de código siguientes crean un conjunto de procedimientos almacenados para administrar los cambios de los metadatos y los datos de la tabla Sales.Customer. Por brevedad, se incluyen los procedimientos para seleccionar los datos y controlar las actualizaciones, pero no se incluyen los de las inserciones y eliminaciones. Para ver ejemplos de procedimientos de inserción y eliminación, vea Scripts de configuración para los temas de procedimientos del proveedor de base de datos. Para obtener una plantilla que le permitirá crear todos estos procedimientos almacenados con mayor facilidad, vea Plantilla de aprovisionamiento de servidor.

En el ejemplo de código completo al final de este tema, muchos de los valores que se pasan a estos procedimientos proceden de las variables de sesión. Se trata de variables integradas que permiten a Sync Framework pasar valores a los comandos durante una sesión de sincronización. Para obtener más información sobre las variables de sesión, vea Usar variables de sesión para la sincronización de colaboración.

Procedimiento para SelectIncrementalChangesCommand

create procedure Sync.sp_Customer_SelectChanges (
    @sync_min_timestamp bigint,
    @sync_metadata_only int,
    @sync_scope_local_id int,
    @sync_initialize int
)
as

--if @sync_initialize = 0
--begin
    -- Perform additional logic if required.
--end
    
begin
    select  t.CustomerId, 
            c.CustomerName,
            c.SalesPerson,
            c.CustomerType, 
            t.sync_row_is_tombstone,
            t.local_update_peer_timestamp as sync_row_timestamp, 
            case when (t.update_scope_local_id is null or t.update_scope_local_id <> @sync_scope_local_id) 
                 then case when (t.restore_timestamp is null) then t.local_update_peer_timestamp else t.restore_timestamp end else t.scope_update_peer_timestamp end as sync_update_peer_timestamp,
            case when (t.update_scope_local_id is null or t.update_scope_local_id <> @sync_scope_local_id) 
                 then t.local_update_peer_key else t.scope_update_peer_key end as sync_update_peer_key,
            case when (t.create_scope_local_id is null or t.create_scope_local_id <> @sync_scope_local_id) 
                 then t.local_create_peer_timestamp else t.scope_create_peer_timestamp end as sync_create_peer_timestamp,
            case when (t.create_scope_local_id is null or t.create_scope_local_id <> @sync_scope_local_id) 
                 then t.local_create_peer_key else t.scope_create_peer_key end as sync_create_peer_key
    from Sales.Customer c right join Sync.Customer_Tracking t on c.CustomerId = t.CustomerId
    where t.local_update_peer_timestamp > @sync_min_timestamp
end

Procedimiento para UpdateCommand

CREATE PROCEDURE Sync.sp_Customer_ApplyUpdate (                                    
        @CustomerId uniqueidentifier,
        @CustomerName nvarchar(100),
        @SalesPerson nvarchar(100),
        @CustomerType nvarchar(100),
        @sync_min_timestamp bigint ,                                
        @sync_row_count int OUT,
        @sync_force_write int)        
AS      
    UPDATE c
    SET c.CustomerName = @CustomerName, c.SalesPerson = @SalesPerson, c.CustomerType = @CustomerType      
    FROM Sales.Customer c JOIN Sync.Customer_Tracking t ON c.CustomerId = t.CustomerId
    WHERE ((t.local_update_peer_timestamp <= @sync_min_timestamp) OR @sync_force_write = 1)
        AND t.CustomerId = @CustomerId  
    SET @sync_row_count = @@rowcount

Procedimiento para UpdateMetadataCommand

create procedure Sync.sp_Customer_UpdateMetadata (
        @CustomerId uniqueidentifier,
        @sync_scope_local_id int,
        @sync_row_is_tombstone int,
        @sync_create_peer_key int,
        @sync_create_peer_timestamp bigint,                 
        @sync_update_peer_key int,
        @sync_update_peer_timestamp timestamp,                      
        @sync_row_timestamp timestamp,
        @sync_check_concurrency int,        
        @sync_row_count int out)        
as  
    declare @was_tombstone int
    select @was_tombstone = sync_row_is_tombstone from Sync.Customer_Tracking 
    where CustomerId = @CustomerId
    
    if (@was_tombstone is not null and @was_tombstone=1 and @sync_row_is_tombstone=0)
        -- tombstone is getting resurrected, update creation version as well
        update Sync.Customer_Tracking set
            [update_scope_local_id] = @sync_scope_local_id, 
            [scope_update_peer_key] = @sync_update_peer_key,
            [scope_update_peer_timestamp] = @sync_update_peer_timestamp,
            [local_update_peer_key] = 0,
            [restore_timestamp] = NULL,
            [create_scope_local_id] = @sync_scope_local_id, 
            [scope_create_peer_key] = @sync_create_peer_key, 
            [scope_create_peer_timestamp] =  @sync_create_peer_timestamp, 
            [sync_row_is_tombstone] = @sync_row_is_tombstone                        
        where CustomerId = @CustomerId          
        and (@sync_check_concurrency = 0 or local_update_peer_timestamp = @sync_row_timestamp)
    else    
        update Sync.Customer_Tracking set
            [update_scope_local_id] = @sync_scope_local_id, 
            [scope_update_peer_key] = @sync_update_peer_key,
            [scope_update_peer_timestamp] = @sync_update_peer_timestamp,
            [local_update_peer_key] = 0,
            [restore_timestamp] = NULL,
            [sync_row_is_tombstone] = @sync_row_is_tombstone                        
        where CustomerId = @CustomerId          
        and (@sync_check_concurrency = 0 or local_update_peer_timestamp = @sync_row_timestamp)
    set @sync_row_count = @@rowcount

Procedimiento para SelectRowCommand

create procedure Sync.sp_Customer_SelectRow
        @CustomerId uniqueidentifier,
        @sync_scope_local_id int
as
    select  t.CustomerId, 
            c.CustomerName,
            c.SalesPerson,
            c.CustomerType, 
            t.sync_row_is_tombstone,
            t.local_update_peer_timestamp as sync_row_timestamp, 
            case when (t.update_scope_local_id is null or t.update_scope_local_id <> @sync_scope_local_id) 
                 then case when (t.restore_timestamp is null) then t.local_update_peer_timestamp else t.restore_timestamp end else t.scope_update_peer_timestamp end as sync_update_peer_timestamp,
            case when (t.update_scope_local_id is null or t.update_scope_local_id <> @sync_scope_local_id) 
                 then t.local_update_peer_key else t.scope_update_peer_key end as sync_update_peer_key,
            case when (t.create_scope_local_id is null or t.create_scope_local_id <> @sync_scope_local_id) 
                 then t.local_create_peer_timestamp else t.scope_create_peer_timestamp end as sync_create_peer_timestamp,
            case when (t.create_scope_local_id is null or t.create_scope_local_id <> @sync_scope_local_id) 
                 then t.local_create_peer_key else t.scope_create_peer_key end as sync_create_peer_key
    from Sales.Customer c right join Sync.Customer_Tracking t on c.CustomerId = t.CustomerId    
    where c.CustomerId = @CustomerId 

Procedimiento para SelectMetadataForCleanupCommand

CREATE PROCEDURE Sync.sp_Customer_SelectMetadata     
    @metadata_aging_in_days int,
    @sync_scope_local_id int
AS
    IF @metadata_aging_in_days = -1
        BEGIN
            SELECT  CustomerId,
                    local_update_peer_timestamp as sync_row_timestamp,  
                    case when (update_scope_local_id is null or update_scope_local_id <> @sync_scope_local_id) 
                        then case when (restore_timestamp is null) then local_update_peer_timestamp else restore_timestamp end else scope_update_peer_timestamp end as sync_update_peer_timestamp,
                    case when (update_scope_local_id is null or update_scope_local_id <> @sync_scope_local_id) 
                        then local_update_peer_key else scope_update_peer_key end as sync_update_peer_key,
                    case when (create_scope_local_id is null or create_scope_local_id <> @sync_scope_local_id) 
                        then local_create_peer_timestamp else scope_create_peer_timestamp end as sync_create_peer_timestamp,
                    case when (create_scope_local_id is null or create_scope_local_id <> @sync_scope_local_id) 
                        then local_create_peer_key else scope_create_peer_key end as sync_create_peer_key
            FROM Sync.Customer_Tracking
            WHERE sync_row_is_tombstone = 1
        END
    
    ELSE
        BEGIN
            SELECT  CustomerId,
                    local_update_peer_timestamp as sync_row_timestamp,  
                    case when (update_scope_local_id is null or update_scope_local_id <> @sync_scope_local_id) 
                        then case when (restore_timestamp is null) then local_update_peer_timestamp else restore_timestamp end else scope_update_peer_timestamp end as sync_update_peer_timestamp,
                    case when (update_scope_local_id is null or update_scope_local_id <> @sync_scope_local_id) 
                        then local_update_peer_key else scope_update_peer_key end as sync_update_peer_key,
                    case when (create_scope_local_id is null or create_scope_local_id <> @sync_scope_local_id) 
                        then local_create_peer_timestamp else scope_create_peer_timestamp end as sync_create_peer_timestamp,
                    case when (create_scope_local_id is null or create_scope_local_id <> @sync_scope_local_id) 
                        then local_create_peer_key else scope_create_peer_key end as sync_create_peer_key
            FROM Sync.Customer_Tracking
            WHERE sync_row_is_tombstone = 1 AND
            DATEDIFF(day, last_change_datetime, GETDATE()) > @metadata_aging_in_days
        END

Conclusión

Este tema sirve de guía en el aprovisionamiento de una base de datos para el seguimiento de cambios. Una vez que se aprovisiona una base de datos, se puede sincronizar con otros nodos. Para obtener más información sobre la configuración y ejecución de la sincronización, vea los temas siguientes: Configurar y ejecutar la sincronización de colaboración (no SQL Server).

Vea también

Conceptos

Sincronizar otras bases de datos compatibles con ADO.NET
Configurar y ejecutar la sincronización de colaboración (no SQL Server)