août 2009 - Messages
Le premier White Paper sur SQL SERVER 2008 R2 vient d’être publié sur Technet
http://technet.microsoft.com/en-us/library/ee364757.aspx
Il aborde le sujet du Multi Server Management
.gif)
L’auteur y aborde plusieurs sujet comme
- L’UCP : Utility Control Point : Instance SQL 2008 chargée de monitorer toute l’infra
- DAC : Data Application Components (Voir aussi le post de Christophe Laporte sur le sujet)
Bonne lecture
Profitez de la fin de l’été et le début de la reprise pour vous former !
Bewise présente une offre promotionnelle à 490 Euros par stagiaire pour des séances de formation d’une durée de 3 jours autour de sujets à haute valeur ajoutée comme :
- Windows Azure
- Nouveautés SQL SERVER 2008 / SQL Azure
- Découverte de .NET 4.0 et Visual Studio 2010
- Parallel FX 4.0
- Silverlight
- WPF
- Expression Blend
Pour tout les renseignements nécessaires, direction le site de Bewise :
http://www.bewise.fr/fr-FR/training/Pages/offres-promotionnelles.aspx
Pour ma part, vous me retrouverez surement pour animer Windows Azure ou les Nouveautés SQL SERVER 2008. Et vu le programme, je vous garantis que vous dormirez bien le soir :)
En avant première je vous donne pour info le contenu de la formation SQL Server 2008, concocté par votre serviteur :
Chapitre 1 Nouveautés du moteur
-
Améliorations du langage T-SQL
-
Les nouveaux types non structurés dans SQL SERVER 2008
-
Améliorations des informations relationnelles
-
Le défi des nouvelles applications : Intégration du spatial
Chapitre 2 : Améliorations, optimisations des performances
-
Recherche Full Text intégré
-
Indexation
-
Service Broker
Chapitre 3 : Améliorations de l’administration
-
Policy Framework
-
Resource Governor
-
Administration multi serveurs
-
Sauvegardes
Chapitre 4 : Monitoring et sécurité
-
Chiffrement
-
Audit
-
Extended Events
-
Data Collector
Chapitre 5 : Réplication et Synchronisation des données
-
Capturer ou traquer les changements
-
La réplication dans SQL SERVER 2008
-
Sync Services for ADO.NET
Chapitre 6 : SQL Server 2008 et le développement
-
Intégration avec Visual Studio et ADO.NET 3.5
-
SqlCmd, SMO, Powershell
-
Intégration continue : Visual Studio Team System 2008 Database GDR R2
Chapitre 7 : SQL SERVER in the Cloud
En attendant votre clé Sql Azure (ptin 15 jours …), vous pouvez toujours récupérer le Training Kit Sql Azure du mois d’Aout
Evidemment dans cette version vous trouverez notamment des chapitre concernant Sql Azure :
Introduction to SQL Azure Building Applications using SQL Azure Scaling Out with SQL Azure Mais aussi toute une série de samples dédié à ce futur système de base de données in the cloud :
Managing Logins and Security in SQL Azure Creating Objects in SQL Azure Migrating a Database Schema to SQL Azure Moving Data Into and Out Of SQL Azure using SSIS Building a Simple SQL Azure App Scaling Out SQL Azure with Database Sharding Bon téléchargement
Voilà depuis ce matin, vous avez la possibilité de tester GRATUITEMENT Sql Azure Database.
Pour se faire, direction le site MSDN de SQL AZURE : http://msdn.microsoft.com/en-us/sqlserver/dataservices/default.aspx
Il vous faudra un compte Connect, seul moyen d’obtenir une clé.
Clé qui d’ailleurs mettra quelques temps à arriver (sachant que je n’ai aucune idée du “temps” que l’attente peut représenter )
Voilà voilà … bon ben … j’attends (hein bon sait’on jamais …)
Tiens je vais faire du TFS pour passer le temps moi là tout de suite !
Les sessions du SqlBits sont disponibles et en ligne :
http://sqlbits.com/information/event4/PublicSessions.aspx
N’hésitez pas à y jeter un coup d’oeil, si vous n’êtes pas allergique à l’anglais 
Il existe dans SQL SERVER CE un système de tracking des changements.
Il est utilisé dans la réplication SQL SERVER 2005 – 2008 tout comme dans le framework Sync Services for ADO.NET
Seulement ce système de change tracking n’est PAS accessible pour nous pauvre développeurs non Microsoft (c’est balot)
A chaque demande “Donnez nous l’accès au Change Tracking sur Sql Server CE”, la réponse était immanquablement “Euh … non, vous en avez pas besoin, dites nous votre problème, on vous montrera comment s’en passer”
Frustrant ….
Aujourd’hui bonne nouvelle, au détour d’un vieux Post qui date de l’année dernière dans mon anglais incertain où je demandais (supplier :)) cette feature, Sean Kelly, Program Manager de Sync Services et SQL Server Compact, annonce la disponibilité de cette fonctionnalité dans une future release de Visual Studio 2010 !
Bonne nouvelle du jour, donc.
Tiens un truc très sympa comme addin à récupérer absolument si vous travaillez avec SQL SERVER CE : Sql Compact SSMS Addin
Tout d’abord, si vous n’avez jamais travaillé avec Compact Edition, dans SSMS, sachez que vous pouvez oublier le clic droit sur une table, pour voir les données ou scripter un Select ..
Et ne parlons même pas du Script Datas …
A la rigueur, dans VS.Net, ça fonctionne, mais bref, c’est pas la joie…
Bizarre me direz vous, et je dirais que vous avez raison ! (Fini à l’arrache le truc hein …)
Bref, voici un superbe addon qui comble cet écueil.
Voici quelques screenshots :
Ah, quand on le voit comme ça c’est pas très impressionnant hein, en fait c’est surtout la première fois que vous utilisez SSMS et Compact Edition “sans” ça que ça choque :)
Bref, que du bonheur
Cette petite merveille vous génère aussi toutes les données et datas de votre base de données SQL COMPACT CE.
Aujourd’hui, je vais répondre à un problème récurrent concernant les synchronisations d’un serveur SQL SERVER 2005 (2008) avec le change tracking activé.
D’où vient cette erreur ?
De temps en temps, votre synchronisation échoue et vous renvoie l’erreur suivante :
SQL Server Change Tracking has cleaned up tracking information
for table Client.
To recover from this error,
the client must reinitialize its local database and try again'
Le problème vient de la période de rétention des données (notamment supprimées) sur le serveur :
Supposons que vous n’ayez pas synchronisé votre application pendant une période de 7 jours. Il se peut donc que certaines données à supprimer sur votre application soient puremment et simplement non disponibles sur le serveur car celui ci a nettoyer ces données.
Votre application se retrouverait donc non correctement synchronisée.
Sync Services envoie avant chaque synchronisation, l’ancre de dernière synchronisation, une sorte de “marque” qui enregistre votre dernière synchronisation. Il stocke cette information et l’envoie via le paramètre @sync_last_received_anchor.
A chaque fin de synchronisation, Sync Services récupère une nouvelle ancre générée via l’instruction :
Select @sync_new_received_anchor = CHANGE_TRACKING_CURRENT_VERSION()
Et avant chaque synchronisation il demande au serveur de vérifier cette fameuse ancre. Si celle-ci est incorrecte, une exception SqlServer est levée :
IF CHANGE_TRACKING_MIN_VALID_VERSION(object_id(N'dbo.Client')) > @sync_last_received_anchor
RAISERROR (N'SQL Server Change Tracking has cleaned up tracking information for table ''%s''.
To recover from this error, the client must reinitialize its local database and try again',
16,
3,
N'dbo.Client')
Solution
J’ai une application de type Synchronisation via un service WCF.
Voici un schéma de la solution de départ :
Je suis donc dans une solution relativement classique, utilisant WCF pour se connecter au serveur.
Voici un schéma récapitulatif de l’architecture de mes projets sous VS :
L’erreur provient du Serveur SQL. C’est lui qui connait la dernière date de synchronisation possible et la dernière date de synchronisation du client en cours.
Il va nous falloir “catcher” l’erreur et la renvoyer au client, lui demandant de resynchroniser totalement son application.
Voici l’ordre d’exécution:
- Tentative de synchronisation du client. Envoie des infos nécessaires au serveur
- Récupération coté serveur de la demande. Levé de l’exception, pour cause de “ça fait trop longtemps que t’es pas venu te synchroniser vilain”. Renvoie de l’erreur au client
- Récupération de l’erreur coté client. Nettoyage de la base de donnée locale, en vue d’une resynchro complète. Demande de resynchro.
- Récupération coté serveur d’une demande de synchro complète. Envoie des données au client
Coté Serveur
Premièrement, il nous faut récupérer l’erreur coté client. Il est donc important d’indiquer à WCF que les erreurs doivent être remontées sur le client.
Je marque donc la classe héritant de mon interface avec un ServiceBehavior particulier
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public partial class DonutSyncSyncService : object, IDonutSyncSyncContract
{
private DonutSyncServerSyncProvider _serverSyncProvider;
public DonutSyncSyncService()
public virtual SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession)
public virtual SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession)
public virtual SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession)
public virtual SyncServerInfo GetServerInfo(SyncSession syncSession)
}
Nous allons maintenant récupérer l’erreur générée par SQL SERVER :
Dans chaque corps de méthode (ApplyChanges, GetChanges, GetSchema, GetServerInfo) je rajoute le code suivant (je prends pour exemple ApplyChanges, le code est indentique pour la partie Catch, sur les autres méthodes)
public virtual SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession)
{
try
{
return this._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
}
catch (SyncException se)
{
if (se.ErrorNumber == SyncErrorNumber.StoreException)
{
SqlException sqlExcept = se.InnerException as SqlException;
if (sqlExcept != null && sqlExcept.Class == 16 && sqlExcept.State == 3)
{
throw new ApplicationException("ChangeTrackingCleanedUp", se);
}
}
throw se;
}
catch (Exception ex)
{
throw ex;
}
}
Vous noterez que pour récupérer l’erreur correcte, je vérifie 3 choses :
- L’erreur est une SyncException : C’est bien une erreur générée par Sync Services.
- L’innerException est une SqlException : C’est au départ une erreur levée par Sql Server
- La Class et le State de l’erreur sont respectivement 16 et 3 (données générées par le RAISERROR des instructions de synchronisations)
Une fois récupérée, je génère une erreur simple à comprendre coté client, coté le mot clé “ChangeTrackingCleanUp”.
Coté Client
Il va me falloir, coté client, récupérer cette erreur et la traiter correctement:
- Récupérer l’erreur contenue dans une CommunicationException
- Récupérer le message indiquant “ChangeTrackingCleanUp”
- Réinitialiser la base de donnée cliente pour une synchro totale.
- Relancer la synchro (aprés demande ou non à l’utilisateur)
Comment marquer la base de données locale pour une synchro Totale ?
- Vous écrasez la base de donnée locale
- Vous effacez les informations de synchronisations de chaque table
Dans le premier cas, vous perdez toutes les informations des tables. Pas grave me direz vous, si vous refaites une synchro totale. SAUF si votre utilisateur a saisi des données supplémentaires entre temps. Dans ce cas là elle sont perdues.
Dans le deuxième cas, les tables sont marquées pour synchro totale, mais les dernière modifications et insertions sont tout de même envoyées au serveur.
Comment marquer une table pour synchro complète . En indiquant sont LastReceivedAnchor à null:
sqlCeProvider.SetTableReceivedAnchor(st.TableName, new SyncAnchor());
Je me suis fait une petite méthode qui lance une synchro avec réinitialisation ou non des tables, comme suit :
public SyncStatistics Synchronize(bool reinit)
{
if (!reinit)
return base.Synchronize();
SqlCeClientSyncProvider sqlCeProvider;
sqlCeProvider = (SqlCeClientSyncProvider)this.LocalProvider;
foreach (SyncTable st in this.Configuration.SyncTables)
{
if (st.SyncDirection != SyncDirection.Snapshot)
{
sqlCeProvider.SetTableReceivedAnchor(st.TableName, new SyncAnchor());
}
}
return base.Synchronize();
}
Il ne reste plus qu’à lancer la synchro, vérifier les erreurs et relancer si nécessaire :
DonutSyncSyncContractClient proxy = new DonutSyncSyncContractClient("WSHttpBinding_IDonutSyncSyncContract");
DonutSyncSyncAgent myAgent = new DonutSyncSyncAgent(proxy);
SyncParameter param = new SyncParameter("@OwnerEmployeId", DonutSettings.Default.EmployeId);
myAgent.Configuration.SyncParameters.Add(param);
try
{
var stats = myAgent.Synchronize(false);
}
catch (TargetInvocationException ex)
{
if (ex.InnerException != null && ex.InnerException.Message == "ChangeTrackingCleanedUp")
{
try
{
var stats = myAgent.Synchronize(true);
}
catch
{
// Serious Error need to be catched here
}
}
}
Voilà votre application est resynchronisée correctement.
Bonne synchro !
Pour les abonnées MSDN et TechNet
Y’a plus qu’à télécharger tout ça !

Hum ça sent bon tout ça !
