Microsoft Sync Framework - FAQ -

 

NOTAS:

A fecha de 6 de enero de 2009.

Versiones:

  • Microsoft Sync Framework 1.0
    • Sync Services for ADO.NET 2.0
  • Microsoft Sync Framework 2.0 CTP1
  • Sync Services for ADO.NET for Devices 1.0
  • Microsoft Sync Framework for devices 1.0 CTP1

General

1.- ¿Que es Microsft Sync Framework 1.0?

Es la respuesta de Microsoft a los escenarios ocasionalmente conectados. MSF 1.0 es la primera versión de un marco de desarrollo que permite el desarrollo de cualquier tipo de solución que requiera de algún tipo de sincronización en escenarios off-line de cualquier tipo de origen de datos sobre cualquier protocolo o tipo de red y exponerlos como servicios WCF.

 2.- ¿Con que producto se distribuye? / ¿Dónde puedo obtenerlo?

Finalmente, MSF 1.0 se distribuye con SQL Server 2008 debido a su afinidad en contextos de sincronización de datos y con Visual Studio 2008 .NET SP1. Sin embargo, también podemos descargarlo desde el siguiente enlace.

3.- ¿Es gratuito?

Si, sin embargo contiene unas cláusulas especiales que deben ser consultadas con Microsoft si MSF va a ser utilizado en plataformas que no estén basadas en Windows mediante licencias comerciales y kits de portabilidad.

4.- ¿Puedo utilizar Microsoft Sync Framework sobre sistemas operativos Windows 64 bits?

Sí. Soporta además de x86, AMD64 y IA64.

4.- ¿Qué relación tienen Sync Services for ADO.NET y Microsoft Sync Framework?

Sync Services for ADO.NET es uno de los tres proveedores Built-In de MSF y está orientada específicamente a la sincronización de orígenes de datos accesibles mediante ADO.NET.

5.- ¿Y los File Sync Services?

Idem. Sin embargo File Sync está orientado a la sincronización de archivos y carpetas.

6.- Pero, ¿Qué son los proveedores de sincronización?

Son orígenes susceptibles de sincronización y pueden ser de naturaleza heterogénea. MSF provee tres proveedores listos para usar, orientados a datos, archivos y SSE, agrupados en Sync Services for ADO.NET, File Sync y RSS Sync Feed, respectivamente.

7.- En definitiva, ¿qué incluye Microsoft Sync Framework 1.0?

MSF incluye:

  • Un proveedor específico para la sincronización de orígenes de datos agrupados en Sync Services for ADO.NET 2.0 de los que hay que distinguir dos tipos diferentes de escenarios: off-line y peer-to-peer.
  • Un proveedor específico para la sincronización de archivos y carpetas agrupados en File Sync Services.
  • Un proveedor específico para la sincronización de SSE(Simple Sharing Extensions) que permite la sincronización de orígenes RSS y Atom.
  • El SDK completo con todas las clases que intervienen en los sistemas de sincronización utilizadas para la creación de proveedores específicos distintos a los tres descritos anteriormente.
  • Los Metadata Services, los cuales permiten el almacenamiento de la metadata en los procesos de sincronización sin la cual, ésta no seria posible.

8.- ¿Podemos crear proveedores customizados?

Si. Todas y cada una de las clases necesarias están definidas en MSF, sin embargo, la creación de proveedores customizados implica un conocimiento más a bajo nivel sobre las características, funcionamiento y actores de la sincronización.

9.- ¿Por que es tan importante SQL Server Compact en MSF?

Los Metadata Services que MSF incorpora por defecto están basados en SQL Server Compact, sin embargo podemos hacer uso de servicios de metadata propios. Asimismo, en los Sync Services for ADO.NET, SQL Server Compact es uno de los proveedores de datos nativos.

10.- ¿Hay algo similar para Windows Mobile?

Sí. Sin embargo el único lanzamiento oficial actualmente es Sync Services for ADO.NET for Devices 1.0 SP1. Por otro lado, MSF 1.0 for Devices está en CTP y se prevé su lanzamiento durante este mismo año 2009. Importante: ¿Por qué Sync Services for ADO.NET está en la versión 2.0 y Microsfoft Sync Framework en la versión 1.0?

11.- ¿Se puede desarrollar para código nativo?

Efectivamente, se pueden desarrollar aplicaciones bajo código nativo con MSF.

Sync Services for ADO.NET

1.- ¿Por qué Sync Services for ADO.NET está en la versión 2.0 y Microsoft Sync Framework en la versión 1.0? / ¿Que diferencia hay entre Sync Services for ADO.NET 1.0 y 2.0?

Con la presentación de las primeras betas de SQL Server Compact 3.5 (versión 2008) se presentó Sync Services for ADO.NET 1.0. Debido a que MSF estaba en fase de desarrollo Sync Services for ADO.NET 1.0 NO estaba construido sobre MSF. Con la aparición de MSF 1.0, se presentó Sync Services for ADO.NET 2.0 es cual SI estaba construido sobre MSF y aportaba una serie de nuevas características. Actualmente Sync Services for ADO.NET 1.0 está desfasado y únicamente se presentó como futura solución en entornos ocasionalmente conectados para clientes ligeros que utilizaran SQL Server Compact 3.5.

2.- ¿Qué tipo de proveedores de datos puedo utilizar? / ¿Puedo utilizar Oracle - MySQL ó XML ?

Se puede utilizar cualquier tipo de proveedor de datos que sea accesible mediante ADO.NET. Sync Services for ADO.NET es especialmente útil con proveedores SQL Server Compact 3.5, debido a que incorpora un LocalProvider específico, y con SQL Server 2008 gracias a que éste puede apoyarse en una de sus nuevas características, la llamada Change Tracking. Es importante comprender que a excepción de SQL Server Compact 3.5, todos los demás proveedores, sean locales o remotos, deben ser implementados como clases que derivan de Microsoft.Synchronization.Server.DbServerSyncProvider, como tal, cualquier origen accesible de ADO.NET debe proveer de un mecanismo que permita el seguimiento de las modificaciones como Change Tracking en SQL Server 2008.

NOTA: Ver punto 8.- Y si no utilizo SQL Server 2008, y por lo tanto no hago uso de Change Tracking…

Las siguientes dos clases muestran en modo de ejemplo como seria un proveedor de sincronización remoto para una base de datos SQL Server 2005, y por lo tanto sin un mecanismo propio de seguimiento de cambios, y un proveedor específico local para SQL Server Compact. Nótese la diferencia y complejidad.

//Clase padre Microsoft.Synchronization.Server.DbServerSyncProvider
//NOTA: Si el origen es SQL Server 2008 hacemos uso de Change Tracking
//Sino, deben utilizarse técnicas invasivas sobre la base de datos como    
//se hace en la siguiente clase de ejemplo.    
//ATENCIÓN: La siguiente clase es únicamente de ejemplo de creación     
//de un proveedor remoto de SQL Server 2005. Sírvase únicamente como    
//referencia. 
public class ServidorSyncProvider : DbServerSyncProvider
{
    public ServidorSyncProvider()
    {
        SqlConnection conexionServidor = new SqlConnection(strServerConnString);
        this.Connection = conexionServidor;

        //creamos comando ancla 
        SqlCommand comandoMomento = new SqlCommand();
        string varMomento = "@" + SyncSession.SyncNewReceivedAnchor;
        comandoMomento.CommandText =
            "SELECT " + varMomento + " = @@DBTS";
        comandoMomento.Parameters.Add(varMomento, SqlDbType.Timestamp);
        comandoMomento.Parameters[varMomento].Direction = ParameterDirection.Output;
        comandoMomento.Connection = conexionServidor;
        this.SelectNewAnchorCommand = comandoMomento;

        //configuramos una tabla para sync bidireccional
        SyncAdapter piezaSyncAdapter = new SyncAdapter("Pieza");

        //
        //comandos de desacarga
        //

        //inserts nuevos del servidor
        SqlCommand piezaIncrInserts = new SqlCommand();
        piezaIncrInserts.CommandText =
            "SELECT [idPieza],[numSerie],[descripcion],[precio],[ultimoCoste],[stock],[stockMinimo]" +
            ",[ubicacionAlmacen],[unidadMedida] FROM [LightMaintenanceSynchSer].[dbo].[Pieza] " +
            "WHERE (InsertTimestamp > @sync_last_received_anchor " +
            "AND InsertTimestamp <= @sync_new_received_anchor " +
            "AND InsertId <> @sync_client_id)";
        piezaIncrInserts.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Timestamp);
        piezaIncrInserts.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Timestamp);
        piezaIncrInserts.Parameters.Add("@" + SyncSession.SyncClientId, SqlDbType.UniqueIdentifier);
        piezaIncrInserts.Connection = conexionServidor;
        piezaSyncAdapter.SelectIncrementalInsertsCommand = piezaIncrInserts;

        //updates nuevos del servidor
        SqlCommand piezaIncrUpdates = new SqlCommand();
        piezaIncrUpdates.CommandText =
            "SELECT [idPieza],[numSerie],[descripcion],[precio],[ultimoCoste],[stock],[stockMinimo]" +
            ",[ubicacionAlmacen],[unidadMedida] FROM [LightMaintenanceSynchSer].[dbo].[Pieza] " +
            "WHERE (UpdateTimestamp > @sync_last_received_anchor " +
            "AND UpdateTimestamp <= @sync_new_received_anchor " +
            "AND UpdateId <> @sync_client_id " +
            "AND NOT (InsertTimestamp > @sync_last_received_anchor " +
            "AND InsertId <> @sync_client_id))";
        piezaIncrUpdates.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Timestamp);
        piezaIncrUpdates.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Timestamp);
        piezaIncrUpdates.Parameters.Add("@" + SyncSession.SyncClientId, SqlDbType.UniqueIdentifier);
        piezaIncrUpdates.Connection = conexionServidor;
        piezaSyncAdapter.SelectIncrementalUpdatesCommand = piezaIncrUpdates;

        //deletes nuevos del servidor
        SqlCommand piezaIncrDeletes = new SqlCommand();
        piezaIncrDeletes.CommandText =
            "SELECT [idPieza],[numSerie],[descripcion],[precio],[ultimoCoste],[stock],[stockMinimo]" +
            ",[ubicacionAlmacen],[unidadMedida] " +
            " FROM [LightMaintenanceSynchSer].[dbo].[Pieza_Tombstone] " +
            "WHERE (@sync_initialized = 1 " +
            "AND DeleteTimestamp > @sync_last_received_anchor " +
            "AND DeleteTimestamp <= @sync_new_received_anchor " +
            "AND DeleteId <> @sync_client_id)";
        piezaIncrDeletes.Parameters.Add("@" + SyncSession.SyncInitialized, SqlDbType.Bit);
        piezaIncrDeletes.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Timestamp);
        piezaIncrDeletes.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Timestamp);
        piezaIncrDeletes.Parameters.Add("@" + SyncSession.SyncClientId, SqlDbType.UniqueIdentifier);
        piezaIncrDeletes.Connection = conexionServidor;
        piezaSyncAdapter.SelectIncrementalDeletesCommand = piezaIncrDeletes;

        //
        //comandos de carga/subida
        //

        //aplicamos inserts al servidor
        SqlCommand piezaInserts = new SqlCommand();
        piezaInserts.CommandText =
            "INSERT INTO [LightMaintenanceSynchSer].[dbo].[Pieza] ([idPieza],[numSerie],[descripcion]"+
            ",[precio],[ultimoCoste],[stock],[stockMinimo],[ubicacionAlmacen],[unidadMedida],[UpdateId],[InsertId]) "+
            "VALUES @idPieza,@numSerie,@descripcion,@precio,@ultimoCoste,@stock,@stockMinimo,@ubicacionAlmacen,"+
            "@unidadMedida, @sync_client_id, @sync_client_id) " +
            "SET @sync_row_count = @@rowcount";
        piezaInserts.Parameters.Add("@idPieza", SqlDbType.Int);
        piezaInserts.Parameters.Add("@numSerie", SqlDbType.NVarChar);
        piezaInserts.Parameters.Add("@descripcion", SqlDbType.NVarChar);
        piezaInserts.Parameters.Add("@precio", SqlDbType.Money);
        piezaInserts.Parameters.Add("@ultimoCoste", SqlDbType.Money);
        piezaInserts.Parameters.Add("@stock", SqlDbType.Int);
        piezaInserts.Parameters.Add("@stockMinimo", SqlDbType.Int);
        piezaInserts.Parameters.Add("@ubicacionAlmacen", SqlDbType.NChar);
        piezaInserts.Parameters.Add("@unidadMedida", SqlDbType.NChar);
        piezaInserts.Parameters.Add("@" + SyncSession.SyncClientId, SqlDbType.UniqueIdentifier);
        piezaInserts.Parameters.Add("@" + SyncSession.SyncRowCount, SqlDbType.Int);
        piezaInserts.Connection = conexionServidor;
        piezaSyncAdapter.InsertCommand = piezaInserts;


        //aplicamos updates al servidor
        SqlCommand piezaUpdates = new SqlCommand();
        piezaUpdates.CommandText =
            "UPDATE Pieza SET " +
            "idPieza = @idPieza " +
            ",numSerie = @numSerie " +
            ",descripcion = @descripcion " +
            ",precio = @precio " +
            ",ultimoCoste = @ultimoCoste " +
            ",stock = @stock " +
            ",stockMinimo = @stockMinimo " +
            ",ubicacionAlmacen = @ubicacionAlmacen " +
            ",unidadMedida = @unidadMedida  " +
            ",UpdateId = @sync_client_id " +
            "WHERE (idPieza = @idPieza) " +
            "AND (@sync_force_write = 1 " +
            "OR (UpdateTimestamp <= @sync_last_received_anchor " +
            "OR UpdateId = @sync_client_id)) " +
            "SET @sync_row_count = @@rowcount";
        piezaInserts.Parameters.Add("@idPieza", SqlDbType.Int);
        piezaInserts.Parameters.Add("@numSerie", SqlDbType.NVarChar);
        piezaInserts.Parameters.Add("@descripcion", SqlDbType.NVarChar);
        piezaInserts.Parameters.Add("@precio", SqlDbType.Money);
        piezaInserts.Parameters.Add("@ultimoCoste", SqlDbType.Money);
        piezaInserts.Parameters.Add("@stock", SqlDbType.Int);
        piezaInserts.Parameters.Add("@stockMinimo", SqlDbType.Int);
        piezaInserts.Parameters.Add("@ubicacionAlmacen", SqlDbType.NChar);
        piezaInserts.Parameters.Add("@unidadMedida", SqlDbType.NChar);
        piezaUpdates.Parameters.Add("@" + SyncSession.SyncClientId, SqlDbType.UniqueIdentifier);
        piezaUpdates.Parameters.Add("@" + SyncSession.SyncForceWrite, SqlDbType.Bit);
        piezaUpdates.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Timestamp);
        piezaUpdates.Parameters.Add("@" + SyncSession.SyncRowCount, SqlDbType.Int);
        piezaUpdates.Connection = conexionServidor;
        piezaSyncAdapter.UpdateCommand = piezaUpdates;

        //aplicamos deletes al servidor            
        SqlCommand piezaDeletes = new SqlCommand();
        piezaDeletes.CommandText =
            "DELETE FROM Pieza " +
            "WHERE (idPieza = @idPieza) " +
            "AND (@sync_force_write = 1 " +
            "OR (UpdateTimestamp <= @sync_last_received_anchor " +
            "OR UpdateId = @sync_client_id)) " +
            "SET @sync_row_count = @@rowcount " +
            "IF (@sync_row_count > 0)  BEGIN " +
            "UPDATE Pieza_Tombstone " +
            "SET DeleteId = @sync_client_id " +
            "WHERE (idPieza = @idPieza) " +
            "END";
        piezaDeletes.Parameters.Add("@idPieza", SqlDbType.UniqueIdentifier);
        piezaDeletes.Parameters.Add("@" + SyncSession.SyncForceWrite, SqlDbType.Bit);
        piezaDeletes.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Timestamp);
        piezaDeletes.Parameters.Add("@" + SyncSession.SyncClientId, SqlDbType.UniqueIdentifier);
        piezaDeletes.Parameters.Add("@" + SyncSession.SyncRowCount, SqlDbType.Int);
        piezaDeletes.Connection = conexionServidor;
        piezaSyncAdapter.DeleteCommand = piezaDeletes;

         //añadimos el adaptador
        this.SyncAdapters.Add(piezaSyncAdapter);
    }
}

Ejemplo de implementación del proveedor local para SQL Server Compact

//Proveedor local SQL Server Compact
public class ClienteSyncProvider : SqlCeClientSyncProvider
{

    public ClienteSyncProvider()
    {
        //Incializamos la cadena de conexión para la base de datos sql ce.
        this.ConnectionString = strClientConnString;

        //pese a que no es necesario podemos intervenir durante y despues de la creación del esquema de la base de datos local
        this.CreatingSchema += new EventHandler<CreatingSchemaEventArgs>(ClienteSyncProvider_CreatingSchema);
        this.SchemaCreated += new EventHandler<SchemaCreatedEventArgs>(ClienteSyncProvider_SchemaCreated);
    }

    private void ClienteSyncProvider_CreatingSchema(object sender, CreatingSchemaEventArgs e)
    {
        Console.Write("Creating schema for " + e.Table.TableName + " | ");
        //e.Schema.Tables["Pieza"].Columns["idPieza"].RowGuid = true;
    }

    private void ClienteSyncProvider_SchemaCreated(object sender, SchemaCreatedEventArgs e)
    {
        Console.WriteLine("Schema created for " + e.Table.TableName);
    }

}

3.- ¿Substituyen Sync Services for ADO.NET a RDA?

NO. Sync Services for ADO.NET NO pretende sustituir a RDA. Sin embargo, Microsoft ha anunciado que no seguirá evolucionando RDA y mantendrá el soporte a ésta en tanto en cuanto existan clientes que basen sus soluciones de sincronización en base a esta tecnología.

4.- Sync Services for ADO.NET funcionan únicamente para base de datos SQL Server Compact, ¿Cierto?

Falso. Pese a que existe un proveedor específico para SQL Server Compact 3.5, Sync Services for ADO.NET 2.0 puede ser utilizado con cualquier proveedor de datos. Sin embargo, para aquellos proveedores distintos a SQL Server Compact, deberemos implementar la lógica de funcionamiento para cada uno de ellos. Actualmente existen algunos proveedores desarrollados como por ejemplo el de SQL Server Express.

5.- ¿Qué tipos de escenarios de sincronización soporta Sync Services for ADO.NET 2.0?

Básicamente se distinguen dos tipos de escenarios:

  • Escenarios off-line: este tipo de escenarios tienen la particularidad de que existe un único proveedor remoto y uno o varios proveedores locales los cuales pueden estar o no conectados en línea.
  • Escenarios de colaboración o peer-to-peer: sin embargo aquí no existe la figura de remoto o local. Sencillamente todos son proveedores se sincronizan entre sí ya que son proveedores de igual a igual.
Escenarios off-line Escenarios de colaboración o punto a punto

6.- ¿Existe algún proveedor para SQL Server Express?

Sí. Pero es de código abierto y están bajo licencia Microsoft Public License, con lo que no hay garantías de uso, pese que a por mi experiencia funciona bastante bien (al menos en escenarios sencillos).

7.- ¿En qué punto, exactamente se unen Sync Services for ADO.NET 2.0 y la nueva característica de SQL Server 2008 Change Tracking?

Ante un escenarios de sincronización de dos proveedores como pueden ser SQL Server Compact y SQL Server 2008, Sync Services for ADO.NET 2.0 aporta un proveedor específico para SQL Server Compact en el cual apenas hay que hacer nada. Este proveedor se encarga de:

  • Insertar los cambios propagados desde el origen de datos remoto
  • Propagar sus propios cambios al origen de datos remoto
  • Manejar los conflictos, si los hay.

Por otro lado, el proveedor remoto (SQL Server 2008) realizará:

  • Obtener todos los cambios acontecidos sobre las tablas o conjunto de datos susceptibles de sincronización y propagarlos al proveedor local. –> Aqui entra en escena Change Tracking!!!
  • Aplicar los cambios propagados desde el proveedor local a la base de datos SQL Server 2008.
  • Manejo y control de conflictos.

Para el proveedor de SQL Server 2008, todo el control de cambios acontecidos en el mismo pueden ser controlados por Change Tracking. Change Tracking mantendrá durante el espacio de tiempo especificado todos los cambios realizados sobre las tablas habilitadas para tal fin.

8.- Y si no utilizo SQL Server 2008, y por lo tanto no hago uso de Change Tracking…

Deberás crear un mecanismo de seguimiento de filas mediante la inserción de columnas que determinen el cuándo y quién ha añadido o modificado cada una de las fila. Esto es una técnica invasiva con lo que conlleva una mayor sobrecarga de información. Para las filas que se eliminen se deben utilizar desencadenadores y “tablas lápida” para almacenar las filas eliminadas asi como la información de versión representada mediante RowGuid Columns.

Por ejemplo,

La tabla Customer de la base de datos Northwind tiene el siguiente esquema:

CREATE TABLE SyncSamplesDb.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)

Siguiendo las instrucciones de la siguiente tabla de la librería del Microsoft Sync Framework Developer Center, vamos a configurar la tabla para que detecte las modificaciones bidireccionales de inserción, modificación y eliminación de datos y para ello primero añadimos las columnas que realizaran el seguimiento:

ALTER TABLE SyncSamplesDb.Sales.Customer 
    ADD UpdateTimestamp timestamp
ALTER TABLE SyncSamplesDb.Sales.Customer 
    ADD InsertTimestamp binary(8) DEFAULT @@DBTS + 1
ALTER TABLE SyncSamplesDb.Sales.Customer 
    ADD UpdateId uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'
ALTER TABLE SyncSamplesDb.Sales.Customer 
    ADD InsertId uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'

Y las indexamos con índices no clusterizados.

CREATE NONCLUSTERED INDEX IX_Customer_UpdateTimestamp
ON Sales.Customer(UpdateTimestamp)

CREATE NONCLUSTERED INDEX IX_Customer_InsertTimestamp
ON Sales.Customer(InsertTimestamp)

CREATE NONCLUSTERED INDEX IX_Customer_UpdateId
ON Sales.Customer(UpdateId)

CREATE NONCLUSTERED INDEX IX_Customer_InsertId
ON Sales.Customer(InsertId)

Debido a que queremos realizar el seguimiento de eliminaciones, crearemos las tabla lápida.

CREATE TABLE SyncSamplesDb.Sales.Customer_Tombstone(
    CustomerId uniqueidentifier NOT NULL PRIMARY KEY NONCLUSTERED, 
    CustomerName nvarchar(100) NOT NULL,
    SalesPerson nvarchar(100) NOT NULL,
    CustomerType nvarchar(100) NOT NULL,
    DeleteId uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
    DeleteTimestamp timestamp)

Y por lo tanto, debemos crear, además, el desencadenador.

CREATE TRIGGER Customer_DeleteTrigger 
ON SyncSamplesDb.Sales.Customer FOR DELETE 
AS 
BEGIN 
    SET NOCOUNT ON
    DELETE FROM SyncSamplesDb.Sales.Customer_Tombstone 
        WHERE CustomerId IN (SELECT CustomerId FROM deleted)
    INSERT INTO SyncSamplesDb.Sales.Customer_Tombstone (CustomerId, CustomerName, SalesPerson, CustomerType) 
    SELECT CustomerId, CustomerName, SalesPerson, CustomerType FROM deleted
    SET NOCOUNT OFF
END

Finalmente, los índices de la tabla lápida.

CREATE CLUSTERED INDEX IX_Customer_Tombstone_DeleteTimestamp
ON Sales.Customer_Tombstone(DeleteTimestamp)

CREATE NONCLUSTERED INDEX IX_Customer_Tombstone_DeleteId
ON Sales.Customer_Tombstone(DeleteId)

Más info: How to: Use a Custom Change Tracking System

9.- También podría utilizar Data Change Capture en lugar de Change Tracking, ¿no?

No. Debido a la naturaleza asíncrona de Data Change Capture, éste es idóneo para otro tipo de escenarios.

10.- ¿Existe algún tipo de soporte en forma de diseñador o asistentes desde el Visual Studio 2008 .NET?

Si. En nuestros proyectos podemos añadir un elemento llamado base de dato local caché (Local Database Cache),

ElementoLocalDatabase

cuyo diseñador nos permite la creación de una solución basada en Sync Services for ADO.NET.

ConfigureDataSync

11. ¿Cuál es la principal característica diferenciadora de Sync Services for ADO.NET con Merge Replication o RDA?

Hay varias. Empezando por la independencia del protocolo o tipo de red. Sync Services for ADO.NET, además, está orientada a servicios con lo que podemos exponer el proveedor remoto mediante WCF. Además, el control y gestión de conflictos es único ya que nos permite aplicar lógica de negocio para la resolución de los mismos. Por último, podemos hacer un seguimiento de datos a nivel de columna.

12.- ¿Que significa seguimiento a nivel de columna o de fila?

Por defecto, el seguimiento de cambios se realiza a nivel de fila, igual que en Merge replication o RDA. Esto significa que ante la modificación de cualquier columna se evaluará la fila como modificada con lo que tras una sincronización se propagará dicha fila, como elemento básico, al proveedor de destino. El seguimiento a nivel de columna utiliza únicamente las columnas de las filas modificadas para la acción de sincronización, sin embargo, y pese a que la cantidad de información (cambios) es inferior repercute notablemente en el rendimiento de SQL Server y salvo casos excepcionales debería ser evitado. NOTA: Change Tracking de SQL Server 2008 permite el seguimiento a nivel de columna.

13.- ¿Por qué la detección y manejo de conflictos es único?

Porque permite, como dije antes, aplicar lógica de negocio o aplicar comportamientos específicos en base al origen del conflicto. Así pues, podemos predisponer el comportamiento de la sincronización ante un conflicto para que siempre “gane” el proveedor servidor o local, pudiendo incluso combinar los resultados si esto es posible. Si el conflicto es inesperado podemos registrarlo para poder evaluarlo más adelante.

Más Info.

14.- ¿Que se entiende por un conflicto?

Un conflicto es la modificación simultánea durante una sesión de sincronización de unos elementos de datos (ItemData) por dos o más orígenes. Esto da lugar a que ante la acción de sincronización deba intervenir algún tipo lógica que determine cual va a ser el resultado final para todos los participantes. Además, un conflicto puede ser una violación de algún tipo de restricción del motor de la base de datos como por ejemplo una FOREIGN KEY.

File Sync y Feed Sync

1.- ¿Que tipo de archivos puedo sincronizar?

Cualquier tipo de archivo o carpeta compatibles con Win-32 como FAT o NTFS.

2.- ¿Existe alguna aplicación de ejemplo con código?

La más famosa e idónea para comenzar en este tipo de aplicaciones es SyncToy

3.- ¿Qué peculiaridad tiene RSS Sync Feed respecto a File Sync?

Que la sincronización de orígenes SSE únicamente son unidireccionales mientras que en FileSync son bidireccionales.

Published 7/1/2009 8:40 por José Miguel Torres
Comparte este post:
http://geeks.ms/blogs/jmtorres/archive/2009/01/07/microsoft-sync-framework-faq.aspx

Comentarios

# re: Microsoft Sync Framework - FAQ -

Gracias, completísimo, algo así estaba buscando, por cierto, feliz año...

Wednesday, January 7, 2009 11:48 AM por Oscar Montesinos

# re: Microsoft Sync Framework - FAQ -

Gracias Oscar, feliz año igualmente!!

Un abrazo!!

Wednesday, January 7, 2009 1:50 PM por José Miguel Torres

# re: Microsoft Sync Framework - FAQ -

Excelente FAQ, muchas gracias

Wednesday, January 7, 2009 2:46 PM por El Bruno

# re: Microsoft Sync Framework - FAQ -

Muy bueno, gracias

Wednesday, January 7, 2009 7:19 PM por Quique

# re: Microsoft Sync Framework - FAQ -

Genial post. Fijo que te dare la chapa con esto, jeje

Thursday, January 8, 2009 12:27 AM por Jose Antonio Gallego

# re: Microsoft Sync Framework - FAQ -

Muy buen post neng!

Sólo hecho en falta un dato "histórico", y es que antes de ver la luz Microsoft Sync Framework era conocido con el codename "Ibiza" ;-)

Salut!

Miguel

Friday, January 9, 2009 6:30 AM por Miguel LLopis

# re: Microsoft Sync Framework - FAQ -

Gracias por la info neng ;-) No lo sabía que el codename era Ibiza, todo un detalle...

Salut!!

Friday, January 9, 2009 8:23 AM por José Miguel Torres

# re: Microsoft Sync Framework - FAQ -

La polla!

Tuesday, January 13, 2009 5:54 PM por Eduardo Ortega Bermejo

# re: Microsoft Sync Framework - FAQ -

Thanks so much for your imazing issue related to this post. But to detect the best essay writing all people should know something just about university essay.

Tuesday, January 11, 2011 5:07 PM por buy term paper