Sébastien Pertus
Chapitre IV : Sync Services for ADO.NET. Créer un Custom Resolver
Création d’un système de résolution des conflits pendant une synchronisation entre un serveur de données et un client consommateur. Utilisation de Sync Services for ADO.Net
Par Sébastien Pertus publié le 20/10/2008 à 00:42, lu 2967 fois, 7 pages
 2 | Le Projet
Nous allons reprendre la suite de l'article précédent, où nous terminions une synchronisation avec WCF. Enfin presque…
A l'époque la synchronisation s'effectue sur une base de données SQL Server 2005 où nous utilisions Triggers et autre table tombeau.
Aujourd'hui l'avènement de SQL Server 2008 et la mise en place du Service Pack 1 de Visual Studio 2008 nous permettent d'utiliser le Change Tracking SQL SERVER 2008 tout en gardant l'utilisation du Designer Sync de Visual studio 2008, celui-ci ayant été mis à jour pour l'occasion :
 
/content/17ca4685-7c88-4fcc-9de9-44e7e7cb9bf2/image1.gif
 
La solution s'articule autour de 3 projets:
  • Un Client : L'application dans les mains de notre utilisateur final, permettant de modifier, visualiser et supprimer des données à synchroniser, et présentes dans une base de données locale (sous SQL Server Compact Edition)
  • Un Service WCF serveur : Ce service se trouve potentiellement sur le serveur, que ce soit sur un réseau local, ou over http. Vive WCF.
  • Un projet interface : Ce projet regroupe l’ensemble des interfaces accessibles via le client et le serveur. Seule petite modification apportée après la génération du code du SyncDesigner de VS. Cette partie concerne principalement l’architecture WCF.
 
/content/17ca4685-7c88-4fcc-9de9-44e7e7cb9bf2/image2.gif
 
Vous trouverez en plus un projet ServerSpy, uniquement destiné à modifier les données coté serveur, et permettant ainsi de générer (facilement) des conflits.
Les deux rôles principaux lors d’une synchronisation sont répartis entre le fournisseur de synchronisation coté client d’un coté et le fournisseur de synchronisation coté serveur de l’autre coté.
  • ClientSyncProvider : Dans notre cas, un SqlCeClientSyncProvider
  • ServerSyncProvider : Dans notre cas, un DbServerSyncProvider
Chacun de ces fournisseurs de synchronisation a en charge deux principales fonctionnalités :
  • Récupérer les derniers changements à l’instant T depuis la dernière synchronisation.
  • Appliquer des changements survenus à l’instant T depuis la dernière synchronisation.
Ces deux fournisseurs étant gérés et ordonnancés dans le bon ordre par notre SyncAgent.
Les principales méthodes nous concernant sont ApplyChanges et GetChanges, que nous retrouvons dans la définition de chacune des classes abstraites de ces fournisseurs :
Définition d’un fournisseur client :

public abstract class ClientSyncProvider : SyncProvider

{

    protected ClientSyncProvider();

    public abstract Guid ClientId { get; set; }

    public abstract SyncContext GetChanges(

        SyncGroupMetadata groupMetadata, SyncSession syncSession);

    public abstract SyncContext ApplyChanges(

        SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);

 

    public abstract void BeginTransaction(SyncSession syncSession);

 

    public abstract void CreateSchema(SyncTable syncTable, SyncSchema syncSchema);

    public abstract void EndTransaction(bool commit, SyncSession syncSession);

 

    public abstract SyncAnchor GetTableReceivedAnchor(string tableName);

    public abstract SyncAnchor GetTableSentAnchor(string tableName);

    public abstract void SetTableReceivedAnchor(string tableName, SyncAnchor anchor);

    public abstract void SetTableSentAnchor(string tableName, SyncAnchor anchor);

}

Définition d’un fournisseur serveur :

public abstract class ServerSyncProvider : SyncProvider

{

    protected ServerSyncProvider();

    public abstract SyncContext ApplyChanges(

        SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);

    public abstract SyncContext GetChanges(

        SyncGroupMetadata groupMetadata, SyncSession syncSession);

 

    public abstract SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession);

    public virtual SyncServerInfo GetServerInfo(SyncSession syncSession);

}

Lors d’une synchronisation, notre orchestreur de synchronisation, le SyncAgent, va appeler successivement chacune de ces méthodes, dans un ordre bien précis :
  • GetChanges : Récupération des changements coté client.
  • ApplyChanges : Depuis le serveur, application des changements provenant du client.
  • GetChanges : Récupération des changements coté serveur.
  • ApplyChanges : Depuis le client, application des changements provenant du serveur.
 
/content/17ca4685-7c88-4fcc-9de9-44e7e7cb9bf2/image3.gif
 
Nous pouvons énumérer les arguments de chacune de ces méthodes :
  • SyncGroupMetadata : Regroupe l’ensemble des tables à synchroniser, suivant la SyncDirection que vous avez spécifiée, ainsi que diverses informations comme les ancres de chacune des tables.
  • DataSet : Le DataSet contenant les modifications, suppression, insertions à appliquer.
  • SyncSession : Contient les paramètres supplémentaires, l’identifiant de l’appelant, l’identifiant de la session en cours.
Les conflits surviendront lors des phases d’application des changements (ApplyChanges) que ce soit coté serveur comme coté client.
Nous allons voir dans la suite de l’article, que la plupart des cas de résolution s’effectueront coté serveur.
 
» Démarrer une discussion
 
Discussion démarée par realtn le 01/02/2010 à 16:58, 1 commentaire(s).