Sync Services : Resynchro totale
Je viens de recevoir un mail me posant la question d’une resynchro totale entre une base de données “client” SQL Server CE et une base de données “server” Sql Server (2005 oou 2008)
Je n’arrive pas à répondre à ce monsieur, l’adresse mail est invalide, alors tant qu’à faire, je vous fais partager la réponse que j’ai faite, ici :
Le problème de réinitialisation des bases clientes reste à ce jour un des grands soucis à mon sens de Sync Services.
Forcer la resynchronisation totale d’une base de données SDF, soyons franc, ça n’est pas simple.
Le problème :
Vous voulez faire une resynchronisation totale de votre base windows mobile:
Pour cela, il va falloir réinitialiser les métadatas de la base de données SQL Server CE, afin d’indiquer lors de la synchro une nouvelle ancre de synchronisation.
C’est données sont stockée dans les tables systèmes de la base de données Sql Server CE
Ces tables sont interrogeables via la requête suivante :
1: select * from INFORMATION_SCHEMA.TABLES
Vous les trouverez dans la table __sysSyncArticle
1: Select * from __sysSyncArticles
Pour chaque table, vous avez l’ancre de dernier envoi et l’ancre de dernière réception. Malheureusement, ces données ne sont pas modifiable par code, ce sont des tables systèmes.
Ce petit outil vous permet de voir les données plus simplement : http://blogs.msdn.com/agujjar/archive/2008/11/22/sync-inspector-tool-inspecting-client-db-state-for-pending-changes.aspx
La seule solution à mon sens, certes ça reste de la bidouille, consiste à … supprimer la base de données cliente et la recréer.
1ère Solution :
Ecraser le schéma:
Si vous écraser le schéma, lors de la prochaine synchronisation; le schéma de votre base sdf va être recréé, et vos données entièrement rapatriées.
Pour récupérer le schéma, il vous suffit d’appeller la méthode GetSchema() sur le DbProvider Server
Un exemple de code :
1: MyServerSyncProviderProxy server =
this.RemoteProvider as MyServerSyncProviderProxy;
2:
3: Collection<String> lstTables = new Collection<string>();
4:
5: foreach (SyncTable st in this.Configuration.SyncTables)
6: lstTables.Add(st.TableName);
7:
8: SyncSession ss = new SyncSession();
9: var schema = server.GetSchema(lstTables, ss);
Le problème, c’est la présence ou non d’autres tables ne faisant pas partie de votre synchronisation. Vous risquez de ne pas pouvoir recréer le schéma, dû peut être à des relations inter tables ou autre. Dans ce cas, il faudra passer à une autre méthode
2eme solution :
Créer une base pour les tables synchronisées, et une base pour les tables non synchronisées. C’est cette solution que j’utilise pour gérer ce cas particulier.
Dans ce cas, un simple Delete de la base de données, puis une recréation par code de la synchro et le tour est joué.
Pour éviter de recréer systèmatiquement le schéma, ce qui peut provoquer une perte de temps non négligeable, j’ai pris l’habitude d’embarquer dans ma solution une base “vide” appellée master, qui contient toutes les tables à synchroniser vide.
Pour le coup, lors de la demande de resynchro complète, je procède en 3 étapes:
- Je supprime la base de données sdf existante
- Je “Copie colle” la base de données master en la renommant
- Je relance une synchro “classique”
3eme solution
Alors là on sort de la juridiction de Sync Services, c’est passer par la réplication Sql Server.
Ca reste à mon sens la solution la plus robuste, si vous être sûr d’avoir entre votre client et votre serveur, du SQL Server Compact et du SQL Server 2005 (2008)
Voilà, j’espère que tout ceci vous parait plus clair à présent.
Sync Services Future
Attention à l’arrivée de la nouvelle mouture de Sync Services, d’ici la fin d’année, basée sur la nouvelle version de Sync Framework, qui apporte autant d’améliorations du core que de nouveautés.
On parle notamment de synchronisation par Snapshot, et de meilleur performance, il faudra donc jeter un coup d’oeil dessus rapidemment pour savoir si ce cas particulier ne pourra pas à terme etre gérer beaucoup plus facilement !
Bon courage !