Compartir a través de


Tutorial: extender la memoria caché de base de datos local para admitir la sincronización bidireccional

En Visual Studio 2008, la opción Caché de base de datos local configura una base de datos de SQL Server Compact y un conjunto de clases parciales que habilitan Sync Framework. Dado que Visual Studio genera clases parciales, se puede escribir código para agregar funcionalidad de sincronización y seguir manteniendo la capacidad de ver y cambiar valores en el cuadro de diálogo Configurar sincronización de datos. Para obtener más información sobre las clases parciales y la Caché de base de datos local, vea la documentación de Visual Studio 2008.

De forma predeterminada, el cuadro de diálogo Configurar sincronización de datos permite configurar Sync Framework sólo para escenarios de descarga. Esto significa que después de configurar la sincronización de datos, las llamadas a Synchronize sólo descargarán cambios del servidor en la base de datos cliente. Una de las formas más comunes de extender el código de sincronización es configurar la sincronización bidireccional. Esto permite cargar cambios del cliente en el servidor. Para habilitar la sincronización bidireccional, se recomienda extender el código generado de las maneras siguientes:

  • Establezca la dirección de sincronización en bidireccional.

  • Agregue código para administrar los conflictos de sincronización.

  • Quite las columnas de seguimiento del servidor de los comandos de sincronización.

Nota

Visual Studio 2008 utiliza Sync Framework for ADO.NET 1.0 cuando genera el código para la Caché de base de datos local.

Requisitos previos

Antes de iniciar este tutorial, debe completar el tutorial siguiente en la documentación de Visual Studio 2008: "Tutorial: crear una aplicación conectada ocasionalmente". Después de completar ese tutorial, tiene un proyecto que contiene una memoria Caché de base de datos local y una aplicación de formularios Windows Forms que permite descargar los cambios de la tabla Customers de Northwind en una base de datos de SQL Server Compact. Ahora ya está preparado para cargar esta solución de tutorial y agregar funcionalidad bidireccional.

Para abrir la solución OCSWalkthrough

  1. Abra Visual Studio.

  2. En el menú Archivo, abra una solución o proyecto existente, y busque la solución OCSWalkthrough. Se trata del archivo OCSWalkthrough.sln.

Establecer la dirección de sincronización

El cuadro de diálogo Configurar sincronización de datos establece la propiedad SyncDirection en DownloadOnly o Snapshot. Para habilitar la sincronización bidireccional, establezca la propiedad SyncDirection en Bidirectional para cada tabla que desee habilitar para la carga de cambios.

Para establecer la dirección de sincronización

  1. Haga clic con el botón secundario en NorthwindCache.sync y seleccione Ver código. La primera vez que se hace esto, Visual Studio crea un archivo de clase NorthwindCache bajo el nodo NorthwindCache.sync en el Explorador de soluciones. Este archivo contiene una clase parcial NorthwindCacheSyncAgent y se pueden agregar otras clases según sea necesario.

  2. En el archivo de clase NorthwindCache, agregue una línea de código al método NorthwindCacheSyncAgent.OnInitialized():

    public partial class NorthwindCacheSyncAgent 
    {   
        partial void OnInitialized()
        {
            this.Customers.SyncDirection = 
                Microsoft.Synchronization.Data.SyncDirection.Bidirectional;
        }
    }
    
    Partial Public Class NorthwindCacheSyncAgent
    
        Partial Sub OnInitialized()
    
            Me.Customers.SyncDirection = Microsoft.Synchronization.Data.SyncDirection.Bidirectional
    
        End Sub
    
    End Class
    
  3. Abra Form1 en el Editor de código.

  4. En el archivo Form1, modifique la línea de código en el controlador de eventos SynchronizeButton_Click para que incluya las estadísticas de carga y descarga:

    MessageBox.Show("Changes downloaded: " +
        syncStats.TotalChangesDownloaded.ToString() + 
        Environment.NewLine +
        "Changes uploaded: " + syncStats.TotalChangesUploaded.ToString());
    
        MessageBox.Show("Changes downloaded: " & _
    syncStats.TotalChangesDownloaded.ToString & Environment.NewLine & "Changes uploaded: " & _
    syncStats.TotalChangesUploaded.ToString)
    

Para sincronizar y ver estadísticas

  1. Presione F5.

  2. En el formulario, actualice un registro y, a continuación, haga clic en el botón Guardar en la barra de herramientas.

  3. Haga clic en Sincronizar ahora.

  4. Aparece un cuadro de mensaje que contiene información sobre los registros sincronizados. Las estadísticas muestran que se cargó una fila y se descargó otra, aunque no se efectuaron cambios en el servidor. La descarga adicional se produce porque los cambios del cliente se devuelven al cliente una vez aplicados en el servidor. Para obtener más información, vea "Determinar qué cliente realizó un cambio de datos" en Utilizar un sistema de seguimiento de cambios personalizado.

  5. Haga clic en Aceptar para cerrar el cuadro de mensaje, pero deje que la aplicación se siga ejecutando.

Para sincronizar y ver la resolución de conflictos

  1. En el formulario, actualice un registro y, a continuación, haga clic en el botón Guardar.

  2. Con la aplicación todavía en ejecución, utilice el Explorador de servidores/Explorador de bases de datos (u otra herramienta de administración de bases de datos) para establecer conexión con la base de datos servidor.

  3. Para mostrar el comportamiento predeterminado para la resolución de conflictos, en el Explorador de servidores/Explorador de bases de datos, actualice el mismo registro que actualizó en el formulario pero en un valor diferente, y confirme el cambio. (Desplácese a la fila modificada).

  4. Vuelva al formulario y, a continuación, haga clic en Sincronizar ahora.

  5. Compruebe la actualización en la cuadrícula de la aplicación y en la base de datos servidor. Observe que la actualización que efectuó en el servidor ha sobrescrito la actualización en el cliente. Para obtener información sobre cómo cambiar este comportamiento de la resolución de conflictos, vea la sección siguiente de este tema, "Agregar código para administrar los conflictos de sincronización".

Agregar código para administrar los conflictos de sincronización

En Sync Framework, una fila está en conflicto cuando se ha cambiado tanto en el cliente como en el servidor entre sincronizaciones. Sync Framework proporciona un conjunto de características que se pueden utilizar para detectar y resolver conflictos. En este tutorial, agregará tratamiento básico para conflictos en los que la misma fila se ha actualizado en el cliente y en el servidor. Otros tipos de conflictos se derivan de eliminar una fila en una base de datos y actualizarla en otra, o de insertar filas con claves principales duplicadas en ambas bases de datos. Para obtener más información sobre cómo detectar y resolver conflictos, vea Controlar conflictos de datos y errores.

Para agregar tratamiento de conflictos

  • Agregue código para administrar el evento ApplyChangeFailed del servidor y el evento ApplyChangeFailed del cliente. Estos eventos se desencadenan cuando una fila no se puede aplicar a causa de un conflicto o de un error. Los métodos que administran estos eventos en el código de ejemplo comprueban el tipo de conflicto y especifican qué conflictos de actualización de cliente/actualización de servidor se deben resolver forzando que el cambio del cliente se escriba en la base de datos servidor. El comando de sincronización que aplica actualizaciones a la base de datos servidor incluye lógica para reconocer cuándo se debe forzar un cambio. Este comando se incluye en el código que figura en la sección siguiente de este tema, "Quitar las columnas de seguimiento del servidor de los comandos de sincronización".

    Nota

    El código de ejemplo proporciona un ejemplo básico de tratamiento de conflictos. La manera de tratar los conflictos depende de los requisitos de la aplicación y la lógica de negocios.

    La forma de agregar código es diferente en C# y en Visual Basic:

    • En C#, agregue código a NorthwindCache.cs y Form1.cs. En NorthwindCache.cs, agregue el código siguiente después del final de la clase NorthwindCacheSyncAgent:

      public partial class NorthwindCacheServerSyncProvider
      {
      
          partial void OnInitialized()
          {
              this.ApplyChangeFailed +=
                  new System.EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs>
                  (NorthwindCacheServerSyncProvider_ApplyChangeFailed);
          }
      
          private void NorthwindCacheServerSyncProvider_ApplyChangeFailed(object sender,
              Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e)
          {
      
          if (e.Conflict.ConflictType ==
              Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate)
              {
      
              //Resolve a client update / server update conflict by force writing
              //the client change to the server database.
              System.Windows.Forms.MessageBox.Show("A client update / server update conflict " +
                                                      "was detected at the server.");
              e.Action = Microsoft.Synchronization.Data.ApplyAction.RetryWithForceWrite;
      
              }
      
          }
      }
      
      public partial class NorthwindCacheClientSyncProvider
      {
      
          public void AddHandlers()
          {
              this.ApplyChangeFailed +=
                  new System.EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs>
                  (NorthwindCacheClientSyncProvider_ApplyChangeFailed);
          }
      
          private void NorthwindCacheClientSyncProvider_ApplyChangeFailed(object sender,
              Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e)
          {
      
              if (e.Conflict.ConflictType ==
                  Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate)
              {
      
                  //Resolve a client update / server update conflict by keeping the 
                  //client change.
                  e.Action = Microsoft.Synchronization.Data.ApplyAction.Continue;
      
              }
      
          }
      }
      

      En Form1.cs, modifique el código en el controlador del evento SynchronizeButton_Click para que llame al método AddHandlers que agregó a NorthwindCache.cs en el paso anterior:

      NorthwindCacheSyncAgent syncAgent = new NorthwindCacheSyncAgent();
      
      NorthwindCacheClientSyncProvider clientSyncProvider =
          (NorthwindCacheClientSyncProvider)syncAgent.LocalProvider;
      clientSyncProvider.AddHandlers();
      
      Microsoft.Synchronization.Data.SyncStatistics syncStats = 
          syncAgent.Synchronize();
      
    • En Visual Basic, en NorthwindCache.vb agregue el código siguiente después de la instrucción End Class para la clase NorthwindCacheSyncAgent.

      Partial Public Class NorthwindCacheServerSyncProvider
      
          Private Sub NorthwindCacheServerSyncProvider_ApplyChangeFailed( _
              ByVal sender As Object, ByVal e As  _
              Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs) _
              Handles Me.ApplyChangeFailed
      
              If e.Conflict.ConflictType = _
                  Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate Then
      
                  'Resolve a client update / server update conflict by force writing
                  'the client change to the server database.
                  MessageBox.Show("A client update / server update conflict was detected at the server.")
                  e.Action = Microsoft.Synchronization.Data.ApplyAction.RetryWithForceWrite
      
              End If
      
          End Sub
      
      End Class
      
      Partial Public Class NorthwindCacheClientSyncProvider
      
          Private Sub NorthwindCacheClientSyncProvider_ApplyChangeFailed( _
              ByVal sender As Object, ByVal e As  _
              Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs) _
              Handles Me.ApplyChangeFailed
      
              If e.Conflict.ConflictType = _
                  Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate Then
      
                  'Resolve a client update / server update conflict by keeping the 
                  'client change.
                  e.Action = Microsoft.Synchronization.Data.ApplyAction.Continue
      
              End If
      
          End Sub
      
      End Class
      

Para sincronizar y ver la resolución de conflictos

  1. Presione F5.

  2. En el formulario, actualice un registro y, a continuación, haga clic en el botón Guardar.

  3. En el Explorador de servidores/Explorador de bases de datos, actualice el mismo registro que actualizó en el formulario pero en un valor diferente, y confirme el cambio.

  4. Vuelva al formulario y, a continuación, haga clic en Sincronizar ahora.

  5. Compruebe la actualización en la cuadrícula de la aplicación y en la base de datos servidor. Observe que la actualización que efectuó en el cliente ha sobrescrito la actualización en el servidor.

Quitar las columnas de seguimiento del servidor de los comandos de sincronización.

Cuando se crea la memoria Caché de base de datos local, las columnas que se utilizan para el seguimiento de cambios en la base de datos servidor se descargan en el cliente. (En este tutorial, las columnas son CreationDate y LastEditDate). Para admitir la sincronización bidireccional y ayudar a garantizar la convergencia de datos en el cliente y el servidor, quite estas columnas de los comandos SQL que aplican cambios a la base de datos servidor. También puede quitar las columnas de los comandos que seleccionan los cambios del servidor para aplicarlos al cliente, pero no es necesario. Debido a las restricciones en algunos cambios de esquema en la base de datos cliente, las columnas no se pueden quitar. Para obtener más información acerca de los comandos de sincronización, vea Especificar una sincronización de instantáneas, de descarga, de carga y bidireccional.

Nota

Si utiliza el seguimiento de cambios de SQL Server, las columnas de seguimiento no se agregan a las tablas. En este caso, no tiene que cambiar los comandos que aplican cambios al servidor.

Para quitar las columnas de seguimiento de los comandos de sincronización

  • Agregue el código siguiente a la clase NorthwindCache (NorthwindCache.vb o NorthwindCache.cs) después de la instrucción End Class para la clase NorthwindCacheServerSyncProvider. En este código vuelven a definirse dos comandos que se establecen como propiedades del objeto SyncAdapter en la tabla Customers: las propiedades InsertCommand y UpdateCommand. Los comandos que se generaron mediante el cuadro de diálogo Configurar sincronización de datos contenían referencias a las columnas CreationDate y LastEditDate. Estos comandos se volvieron a definir en el método OnInitialized de la clase CustomersSyncAdapter. No se vuelve a definir la propiedad DeleteCommand porque no afecta a las columnas CreationDate o LastEditDate.

    Las variables de cada comando SQL se utilizan para pasar datos y metadatos entre Sync Framework, el cliente y el servidor. Las variables de sesión siguientes se utilizan en los comandos que figuran más abajo:

    • @sync_row_count: devuelve el número de filas afectadas por la última operación en el servidor. En las bases de datos SQL Server, @@ROWCOUNT proporciona el valor de esta variable.

    • @sync_force_write: se usa para forzar la aplicación de un cambio que no pudo aplicarse a causa de un conflicto o de un error.

    • @sync_last_received_anchor: se usa para definir el conjunto de cambios que se sincronizan durante una sesión.

    Para obtener más información sobre variables de sesión, vea Usar variables de sesión.

    public partial class CustomersSyncAdapter
    {
    
        partial void OnInitialized()
        {
    
        //Redefine the insert command so that it does not insert values 
        //into the CreationDate and LastEditDate columns.
        System.Data.SqlClient.SqlCommand insertCommand = new System.Data.SqlClient.SqlCommand();
    
        insertCommand.CommandText = "INSERT INTO dbo.Customers ([CustomerID], [CompanyName], " +
            "[ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], " +
            "[Country], [Phone], [Fax] )" +
            "VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, " +
            "@Region, @PostalCode, @Country, @Phone, @Fax) SET @sync_row_count = @@rowcount";
        insertCommand.CommandType = System.Data.CommandType.Text;
        insertCommand.Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar);
        insertCommand.Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@Address", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@City", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@Region", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@Country", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar);
        insertCommand.Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int);
        insertCommand.Parameters["@sync_row_count"].Direction = 
            System.Data.ParameterDirection.Output;
    
        this.InsertCommand = insertCommand;
    
    
        //Redefine the update command so that it does not update values 
        //in the CreationDate and LastEditDate columns.
        System.Data.SqlClient.SqlCommand updateCommand = new System.Data.SqlClient.SqlCommand();
    
        updateCommand.CommandText = "UPDATE dbo.Customers SET [CompanyName] = @CompanyName, [ContactName] " +
            "= @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] " +
            "= @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, " +
            "[Phone] = @Phone, [Fax] = @Fax " +
            "WHERE ([CustomerID] = @CustomerID) AND (@sync_force_write = 1 " +
            "OR ([LastEditDate] <= @sync_last_received_anchor)) SET @sync_row_count = @@rowcount";
        updateCommand.CommandType = System.Data.CommandType.Text;
        updateCommand.Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@Address", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@City", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@Region", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@Country", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar);
        updateCommand.Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar);
        updateCommand.Parameters.Add("@sync_force_write", System.Data.SqlDbType.Bit);
        updateCommand.Parameters.Add("@sync_last_received_anchor", System.Data.SqlDbType.DateTime);
        updateCommand.Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int);
        updateCommand.Parameters["@sync_row_count"].Direction = 
            System.Data.ParameterDirection.Output;
    
        this.UpdateCommand = updateCommand;
    
        }
    }
    
    Partial Public Class CustomersSyncAdapter
        Private Sub OnInitialized()
    
            'Redefine the insert command so that it does not insert values 
            'into the CreationDate and LastEditDate columns.
            Dim insertCommand As New System.Data.SqlClient.SqlCommand
            With insertCommand
                .CommandText = "INSERT INTO dbo.Customers ([CustomerID], [CompanyName], " & _
                    "[ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], " & _
                    "[Country], [Phone], [Fax] )" & _
                    "VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, " & _
                    "@Region, @PostalCode, @Country, @Phone, @Fax) SET @sync_row_count = @@rowcount"
                .CommandType = System.Data.CommandType.Text
                .Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar)
                .Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Address", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@City", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Region", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Country", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int)
                .Parameters("@sync_row_count").Direction = ParameterDirection.Output
            End With
    
            Me.InsertCommand = insertCommand
    
    
            'Redefine the update command so that it does not update values 
            'in the CreationDate and LastEditDate columns.
            Dim updateCommand As New System.Data.SqlClient.SqlCommand
            With updateCommand
                .CommandText = "UPDATE dbo.Customers SET [CompanyName] = @CompanyName, [ContactName] " & _
                    "= @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] " & _
                    "= @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, " & _
                    "[Phone] = @Phone, [Fax] = @Fax " & _
                    "WHERE ([CustomerID] = @CustomerID) AND (@sync_force_write = 1 " & _
                    "OR ([LastEditDate] <= @sync_last_received_anchor)) SET @sync_row_count = @@rowcount"
                .CommandType = System.Data.CommandType.Text
                .Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Address", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@City", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Region", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Country", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar)
                .Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar)
                .Parameters.Add("@sync_force_write", System.Data.SqlDbType.Bit)
                .Parameters.Add("@sync_last_received_anchor", System.Data.SqlDbType.DateTime)
                .Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int)
                .Parameters("@sync_row_count").Direction = ParameterDirection.Output
            End With
    
            Me.UpdateCommand = updateCommand
    
        End Sub
    
    End Class
    

Para sincronizar y ver una actualización de columna de seguimiento

  1. Presione F5.

  2. En el formulario, actualice un registro cambiando un valor en la columna LastEditDate y, a continuación, haga clic en el botón Guardar.

  3. Vuelva al formulario y, a continuación, haga clic en Sincronizar ahora.

  4. Compruebe la actualización en la cuadrícula de la aplicación y en la base de datos servidor. Observe que el valor de columna del servidor ha sobrescrito la actualización en el cliente. El proceso de la actualización tiene los siguientes pasos:

    1. Sync Framework identifica que una fila se cambió en el cliente.

    2. Durante la sincronización, la fila se carga y se aplica a la tabla en la base de datos servidor. Sin embargo, las columnas de seguimiento no se incluyen en la instrucción de actualización. Sync Framework realiza de forma eficaz una "actualización ficticia" en la tabla.

    3. La fila se devuelve ahora al cliente, pero los comandos que seleccionan los cambios del servidor sí incluyen las columnas de seguimiento. Por lo tanto, el cambio que se realizó en el cliente es sobrescrito por el valor del servidor.

Conclusión

En este tutorial, ha configurado la sincronización bidireccional con tratamiento básico de conflictos y ha resuelto el posible problema de tener las columnas de seguimiento del servidor en la base de datos cliente. Si usa clases parciales, puede extender el código de la Caché de base de datos local de otras maneras significativas. Por ejemplo, puede volver a definir los comandos SQL que seleccionan los cambios de la base de datos servidor para que los datos se filtren cuando se descargan al cliente. Se recomienda leer los temas de procedimiento contenidos en esta documentación para conocer los procedimientos que permiten agregar o cambiar código de sincronización para que se cumplan los requisitos de las aplicaciones. Para obtener más información, vea Programar tareas comunes de sincronización de cliente y servidor.

Vea también

Conceptos

Programar tareas comunes de sincronización de cliente y servidor
Herramientas que facilitan el desarrollo de aplicaciones