Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie benachrichtige ich einen Windows-Dienst (c#) über eine DB-Tabellenänderung (sql 2005)?

Sie haben wirklich nicht viele Möglichkeiten, Änderungen in SQL 2005 zu erkennen. Die meisten davon haben Sie bereits aufgelistet.

Abfragebenachrichtigungen . Dies ist die Technologie, die SqlDependency und seinen Derivaten zugrunde liegt. Weitere Einzelheiten finden Sie unter Die mysteriöse Benachrichtigung . Aber QN ist darauf ausgelegt, ungültig zu machen Ergebnisse, nicht proaktiv über Änderungsinhalte zu informieren. Sie wissen nur, dass sich die Tabelle geändert hat, ohne zu wissen, was sich geändert hat. Auf einem ausgelasteten System wird dies nicht funktionieren, da die Benachrichtigungen ziemlich kontinuierlich kommen.

Protokolllesen . Dies wird von der Transaktionsreplikation verwendet und ist die am wenigsten aufdringliche Methode zum Erkennen von Änderungen. Leider nur für interne Komponenten verfügbar. Selbst wenn Sie das Protokollformat verstehen, besteht das Problem darin, dass Sie die Unterstützung der Engine benötigen, um das Protokoll als „in Verwendung“ zu markieren, bis Sie es lesen, oder es kann überschrieben werden. Nur die Transaktionsreplikation kann diese Art der speziellen Markierung durchführen.

Daten vergleichen . Verlassen Sie sich auf Zeitstempelspalten, um Änderungen zu erkennen. Ist auch Pull-basiert, ziemlich aufdringlich und hat Probleme beim Erkennen von Löschungen.

Anwendungsschicht . Dies ist theoretisch die beste Option, es sei denn, es treten Änderungen an den Daten außerhalb des Anwendungsbereichs auf, in diesem Fall bröckelt es. In der Praxis gibt es immer Änderungen, die außerhalb des Geltungsbereichs der Anwendung auftreten.

Auslöser . Letztendlich ist dies die einzig gangbare Option. Alle auf Auslösern basierenden Änderungsmechanismen funktionieren auf die gleiche Weise, sie stellen die Änderungsbenachrichtigung in eine Warteschlange zu einer Komponente, die die Warteschlange überwacht.

Es gibt immer Vorschläge für eine eng gekoppelte, synchrone Benachrichtigung (über xp_cmdshell, xp_olecreate, CLR, Benachrichtigung mit WCF, was auch immer), aber alle diese Schemata scheitern in der Praxis, weil sie grundlegend fehlerhaft sind:
- sie tun es nicht berücksichtigen Transaktionskonsistenz und Rollbacks
- sie führen Verfügbarkeitsabhängigkeiten ein (das OLTP-System kann nicht fortfahren, wenn die benachrichtigte Komponente nicht online ist)
- sie funktionieren schrecklich, da jede DML-Operation auf einen RPC-Aufruf irgendeiner Form warten muss zu vervollständigen

Wenn die Trigger die Listener nicht wirklich aktiv benachrichtigen, sondern die Benachrichtigungen nur in eine Warteschlange stellen, gibt es ein Problem bei der Überwachung der Benachrichtigungswarteschlange (wenn ich „Warteschlange“ sage, meine ich jede Tabelle, die als Warteschlange fungiert). Die Überwachung impliziert das Abrufen neuer Einträge in der Warteschlange, was bedeutet, dass die Häufigkeit der Überprüfungen korrekt mit der Last der Änderungen in Einklang gebracht und auf Lastspitzen reagiert wird. Das ist überhaupt nicht trivial, sondern sehr schwierig. Es gibt jedoch eine Anweisung in SQL Server, die die Semantik zum Blockieren ohne Ziehen hat, bis Änderungen verfügbar werden:WAITFOR(RECEIVE) . Das bedeutet Service Broker. Sie haben SSB in Ihrem Beitrag mehrmals erwähnt, aber Sie haben zu Recht Angst, es wegen der großen Unbekannten einzusetzen. Aber die Realität ist, dass es bei weitem am besten für die von Ihnen beschriebene Aufgabe geeignet ist.

Sie müssen keine vollständige SSB-Architektur bereitstellen, bei der die Benachrichtigung bis zum Remote-Dienst übermittelt wird (dafür wäre sowieso eine Remote-SQL-Instanz erforderlich, sogar eine Express-Instanz). Alles, was Sie tun müssen, ist, den Moment, in dem die Änderung erkannt wird (der DML-Trigger), von dem Moment zu entkoppeln, in dem die Benachrichtigung zugestellt wird (nachdem die Änderung festgeschrieben wurde). Dazu benötigen Sie lediglich eine lokale SSB-Warteschlange und einen Dienst. Im Trigger SENDEN eine Änderungsmitteilung an den lokalen Dienst. Nachdem die ursprüngliche DML-Transaktion festgeschrieben wurde, wird die Dienstprozedur aktiviert und übermittelt die Benachrichtigung, beispielsweise unter Verwendung von CLR. Ein ähnliches Beispiel finden Sie unter Asynchronous T-SQL .

Wenn Sie diesen Weg gehen, müssen Sie einige Tricks lernen, um einen hohen Durchsatz zu erreichen, und Sie müssen das Konzept der geordneten Zustellung von Nachrichten in SSB verstehen. Ich empfehle Ihnen, diese Links zu lesen:

Über die Mittel, um Änderungen zu erkennen, SQL 2008 anscheinend fügt neue Optionen hinzu:Datenerfassung und Änderungsverfolgung ändern . Ich betone „scheinbar“, da es sich nicht wirklich um neue Technologien handelt. CDC verwendet einen Protokollleser und basiert auf den vorhandenen Transaktionsreplikationsmechanismen. CT verwendet Trigger und ist den existierenden Merge-Replikationsmechanismen sehr ähnlich. Sie sind beide für gelegentliche Verbindungen gedacht Systeme, die synchronisiert werden müssen und daher nicht für Echtzeit-Änderungsbenachrichtigungen geeignet sind. Sie können die Änderungstabellen füllen, aber Ihnen bleibt die Aufgabe, diese Tabellen auf Änderungen zu überwachen, womit Sie genau begonnen haben.