Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment notifier un service Windows (c#) d'un changement de table DB (sql 2005) ?

Vous n'avez vraiment pas beaucoup de façons de détecter les changements dans SQL 2005. Vous avez déjà répertorié la plupart d'entre eux.

Notifications de requête . C'est la technologie qui alimente SqlDependency et ses dérivés, vous pouvez lire plus de détails sur La notification mystérieuse . Mais QN est conçu pour invalider résultats, de ne pas notifier de manière proactive le changement de contenu. Vous saurez seulement que le tableau a changé, sans savoir ce qui a changé. Sur un système occupé, cela ne fonctionnera pas, car les notifications arriveront à peu près en continu.

Lecture du journal . C'est ce qu'utilise la réplication transactionnelle et c'est le moyen le moins intrusif de détecter les changements. Malheureusement n'est disponible que pour les composants internes. Même si vous parvenez à comprendre le format du journal, le problème est que vous avez besoin de l'aide du moteur pour marquer le journal comme "en cours d'utilisation" jusqu'à ce que vous le lisiez, sinon il peut être écrasé. Seule la réplication transactionnelle peut effectuer ce type de marquage spécial.

Comparer les données . S'appuyer sur les colonnes d'horodatage pour détecter les modifications. Est également basé sur l'extraction, assez intrusif et a des problèmes pour détecter les suppressions.

Couche d'application . C'est la meilleure option en théorie, à moins que des modifications ne soient apportées aux données en dehors de la portée de l'application, auquel cas elles s'effondrent. En pratique, il y a toujours les changements se produisant en dehors du champ d'application de l'application.

Déclencheurs . En fin de compte, c'est la seule option viable. Tous les mécanismes de changement basés sur des déclencheurs fonctionnent de la même manière, ils mettent en file d'attente la notification de changement vers un composant qui surveille la file d'attente.

Il y a toujours des suggestions pour faire une notification synchrone étroitement couplée (via xp_cmdshell, xp_olecreate, CLR, notifier avec WCF, etc.), mais tous ces schémas échouent en pratique car ils sont fondamentalement défectueux :
- ils ne le font pas tiennent compte de la cohérence des transactions et des annulations
- ils introduisent des dépendances de disponibilité (le système OLTP ne peut pas continuer à moins que le composant notifié soit en ligne)
- ils fonctionnent horriblement car chaque opération DML doit attendre un appel RPC d'une certaine forme à compléter

Si les déclencheurs ne notifient pas activement les écouteurs, mais ne font que mettre les notifications en file d'attente, il y a un problème dans la surveillance de la file d'attente des notifications (quand je dis "file d'attente", je veux dire toute table qui agit comme une file d'attente). La surveillance implique de rechercher de nouvelles entrées dans la file d'attente, ce qui signifie équilibrer correctement la fréquence des vérifications avec la charge de modifications et réagir aux pics de charge. Ce n'est pas anodin du tout, c'est en fait très difficile. Cependant, il existe une instruction dans le serveur SQL qui a la sémantique pour bloquer, sans tirer, jusqu'à ce que les modifications soient disponibles :ATTENDRE(RECEPTION) . Cela signifie Service Broker. Vous avez mentionné plusieurs fois le SSB dans votre message, mais vous avez, à juste titre, peur de le déployer à cause de la grande inconnue. Mais la réalité est que c'est, de loin, la meilleure solution pour la tâche que vous avez décrite.

Vous n'avez pas besoin de déployer une architecture SSB complète, où la notification est transmise jusqu'au service distant (ce qui nécessiterait de toute façon une instance SQL distante, même une instance Express). Tout ce dont vous avez besoin pour être complice est de découpler le moment où le changement est détecté (le déclencheur DML) du moment où la notification est délivrée (après que le changement a été validé). Pour cela, tout ce dont vous avez besoin est une file d'attente et un service SSB locaux. Dans le déclencheur, vous ENVOYER une notification de modification au service local. Une fois la transaction DML d'origine validée, la procédure de service s'active et délivre la notification, en utilisant CLR par exemple. Vous pouvez voir un exemple de quelque chose de similaire sur T-SQL asynchrone .

Si vous suivez cette voie, vous devrez apprendre quelques astuces pour atteindre un débit élevé et vous devez comprendre le concept de livraison ordonnée des messages en SSB. Je vous recommande de lire ces liens :

À propos des moyens de détecter les changements, SQL 2008 apparemment ajoute de nouvelles options :Change Data Capture and Change Tracking . J'insiste sur « apparemment », puisqu'il ne s'agit pas vraiment de nouvelles technologies. CDC utilise un lecteur de journal et est basé sur les mécanismes de réplication transactionnels existants. CT utilise des déclencheurs et est très similaire aux mécanismes de réplication Merge existants. Ils sont tous deux destinés aux connectés occasionnellement systèmes qui doivent être synchronisés et ne sont donc pas adaptés à la notification des modifications en temps réel. Ils peuvent remplir les tables de modifications, mais il vous reste la tâche de surveiller ces tables pour les modifications, ce qui correspond exactement à votre point de départ.