sql >> Database >  >> RDS >> Sqlserver

Hoe kan ik een Windows-service (c#) op de hoogte stellen van een DB-tabelwijziging (sql 2005)?

Je hebt echt niet zoveel manieren om veranderingen in SQL 2005 te detecteren. De meeste heb je al genoemd.

Berichtmeldingen . Dit is de technologie die SqlDependency en zijn afgeleiden mogelijk maakt, u kunt meer details lezen op De mysterieuze melding . Maar QN is ontworpen om ongeldig te maken resultaten, niet om de inhoud van wijzigingen proactief te melden. U zult alleen weten dat de tabel wijzigingen heeft, zonder te weten wat er is veranderd. Op een druk systeem werkt dit niet, omdat de meldingen vrijwel continu binnenkomen.

Logboek lezen . Dit is wat transactionele replicatie gebruikt en is de minst ingrijpende manier om wijzigingen te detecteren. Helaas is alleen beschikbaar voor interne componenten. Zelfs als je het logformaat begrijpt, is het probleem dat je ondersteuning van de engine nodig hebt om het log te markeren als 'in gebruik' totdat je het leest, of het kan worden overschreven. Alleen transactionele replicatie kan dit soort speciale markeringen uitvoeren.

Gegevens vergelijken . Vertrouw op tijdstempelkolommen om wijzigingen te detecteren. Is ook op pull gebaseerd, behoorlijk opdringerig en heeft problemen met het detecteren van verwijderingen.

Applicatielaag . Dit is in theorie de beste optie, tenzij er wijzigingen optreden in de gegevens buiten de reikwijdte van de toepassing, in welk geval het afbrokkelt. In de praktijk zijn er altijd veranderingen die plaatsvinden buiten de reikwijdte van de toepassing.

Triggers . Uiteindelijk is dit de enige haalbare optie. Alle wijzigingsmechanismen op basis van triggers werken op dezelfde manier, ze zetten de wijzigingsmelding in de wachtrij voor een component die de wachtrij bewaakt.

Er zijn altijd suggesties om een ​​nauw gekoppelde, synchrone melding te doen (via xp_cmdshell, xp_olecreate, CLR, notificeren met WCF, noem maar op), maar al deze schema's mislukken in de praktijk omdat ze fundamenteel gebrekkig zijn:
- dat doen ze niet rekening houden met transactieconsistentie en rollbacks
- ze introduceren beschikbaarheidsafhankelijkheden (het OLTP-systeem kan niet doorgaan tenzij de aangemelde component online is)
- ze presteren vreselijk omdat elke DML-bewerking moet wachten op een RPC-aanroep van een of andere vorm voltooien

Als de triggers de luisteraars niet actief informeren, maar alleen de meldingen in de wachtrij plaatsen, is er een probleem bij het bewaken van de wachtrij voor meldingen (als ik 'wachtrij' zeg, bedoel ik elke tabel die als wachtrij fungeert). Monitoring houdt in dat er nieuwe items in de wachtrij worden gezocht, wat betekent dat de frequentie van controles correct moet worden afgewogen tegen de hoeveelheid wijzigingen en dat moet worden gereageerd op belastingpieken. Dit is helemaal niet triviaal, eigenlijk is het heel moeilijk. Er is echter één instructie in SQL-server die de semantiek heeft om te blokkeren, zonder te trekken, totdat wijzigingen beschikbaar komen:WAITFOR(RECEIVE) . Dat betekent Service Broker. Je noemde SSB meerdere keren in je post, maar je bent, terecht, bang om het in te zetten vanwege het grote onbekende. Maar de realiteit is dat het verreweg het beste past bij de taak die je beschrijft.

U hoeft geen volledige SSB-architectuur te implementeren, waarbij de melding helemaal naar de externe service wordt geleverd (waarvoor sowieso een externe SQL-instantie nodig is, zelfs een Express-instantie). Het enige dat u hoeft te doen is het moment waarop de wijziging wordt gedetecteerd (de DML-trigger) los te koppelen van het moment waarop de melding wordt afgeleverd (nadat de wijziging is doorgevoerd). Hiervoor hebt u alleen een lokale SSB-wachtrij en -service nodig. In de trigger VERZENDEN een wijzigingsmelding aan de lokale dienst. Nadat de oorspronkelijke DML-transactie is vastgelegd, wordt de serviceprocedure geactiveerd en bezorgt de melding, bijvoorbeeld met behulp van CLR. U kunt een voorbeeld van iets dergelijks zien op Asynchronous T-SQL .

Als je dat pad bewandelt, zijn er enkele trucjes die je moet leren om een ​​hoge doorvoer te bereiken en je moet het concept van geordende bezorging van berichten in SSB begrijpen. Ik raad je aan deze links te lezen:

Over de middelen om veranderingen te detecteren, SQL 2008 blijkbaar voegt nieuwe opties toe:Gegevens vastleggen en wijzigingen bijhouden . I benadrukt 'blijkbaar', aangezien het niet echt nieuwe technologieën zijn. CDC gebruikt logreader en is gebaseerd op de bestaande Transactionele replicatiemechanismen. CT maakt gebruik van triggers en lijkt sterk op bestaande Merge-replicatiemechanismen. Ze zijn beide bedoeld voor af en toe verbonden systemen die moeten worden gesynchroniseerd en dus niet geschikt zijn voor realtime wijzigingsmeldingen. Ze kunnen de wijzigingstabellen vullen, maar u heeft de taak om deze tabellen te controleren op wijzigingen, en dat is precies waar u bent begonnen.



  1. Opgeslagen procedure uitvoeren vanuit Laravel

  2. Selecteer alle kolommen behalve één in MySQL?

  3. Hoe te ontsnappen aan een enkel aanhalingsteken in letterlijke tekenreeksen met MySQL van Java

  4. MySQL versus bestandsdatabases