sql >> Databasteknik >  >> RDS >> Sqlserver

Hur meddelar man en Windows-tjänst (c#) om en DB-tabelländring (sql 2005)?

Du har verkligen inte så många sätt att upptäcka ändringar i SQL 2005. Du har redan listat de flesta av dem.

Frågemeddelanden . Detta är tekniken som driver SqlDependency och dess derivat, du kan läsa mer information på Det mystiska meddelandet . Men QN är utformad för att ogiltigförklara resultat, inte för att proaktivt meddela ändra innehåll. Du kommer bara att veta att tabellen har förändringar, utan att veta vad som förändrats. På ett upptaget system kommer detta inte att fungera, eftersom aviseringarna kommer i stort sett kontinuerligt.

Loggläsning . Detta är vad transaktionsreplikering använder och är det minst påträngande sättet att upptäcka förändringar. Tyvärr är den endast tillgänglig för interna komponenter. Även om du lyckas förstå loggformatet så är problemet att du behöver stöd från motorn för att markera loggen som 'in use' tills du läser den, annars kan den skrivas över. Endast transaktionsreplikering kan göra denna typ av speciell märkning.

Datajämförelse . Lita på tidsstämpelkolumner för att upptäcka ändringar. Är också pull-baserad, ganska påträngande och har problem med att upptäcka borttagningar.

Applikationslager . Detta är det bästa alternativet i teorin, såvida det inte sker förändringar av data utanför tillämpningsområdet, i vilket fall det faller sönder. I praktiken finns det alltid ändringar som inträffar utanför tillämpningsområdet.

Triggers . I slutändan är detta det enda genomförbara alternativet. Alla ändringsmekanismer baserade på triggers fungerar på samma sätt, de köar ändringsmeddelandet till en komponent som övervakar kön.

Det finns alltid förslag på att göra en tätt kopplad, synkron avisering (via xp_cmdshell, xp_olecreate, CLR, meddela med WCF, you name it), men alla dessa scheman misslyckas i praktiken eftersom de är fundamentalt felaktiga:
- de gör det inte redogör för transaktionskonsistens och återställning
- de inför tillgänglighetsberoenden (OLTP-systemet kan inte fortsätta om inte den aviserade komponenten är online)
- de fungerar fruktansvärt eftersom varje DML-operation måste vänta på ett RPC-anrop av någon form att slutföra

Om triggarna faktiskt inte aktivt meddelar lyssnarna, utan bara ställer upp aviseringarna, finns det problem med att övervaka aviseringskön (när jag säger 'kö' menar jag vilken tabell som helst som fungerar som en kö). Övervakning innebär att man drar efter nya poster i kön, vilket innebär att man balanserar frekvensen av kontroller korrekt med belastningen av ändringar och reagerar på belastningsspikar. Detta är inte trivialt alls, det är faktiskt väldigt svårt. Det finns dock en sats i SQL-servern som har semantiken att blockera, utan att dra, tills ändringar blir tillgängliga:WAITFOR(RECEIVE) . Det betyder Servicemäklare. Du nämnde SSB flera gånger i ditt inlägg, men du är, med rätta, rädd för att distribuera den på grund av det stora okända. Men verkligheten är att den överlägset passar bäst för den uppgift du beskrev.

Du behöver inte distribuera en fullständig SSB-arkitektur, där meddelandet levereras hela vägen till fjärrtjänsten (som skulle kräva en fjärransluten SQL-instans i alla fall, till och med en Express). Allt du behöver göra är att koppla bort ögonblicket när ändringen upptäcks (DML-utlösaren) från det ögonblick då meddelandet levereras (efter att ändringen har genomförts). Allt du behöver för detta är en lokal SSB-kö och service. I triggern SKICKAR ett ändringsmeddelande till den lokala tjänsten. Efter att den ursprungliga DML-transaktionen genomförts, aktiveras och levererar meddelandet, med till exempel CLR. Du kan se ett exempel på något liknande detta på Asynchronous T-SQL .

Om du går på den vägen finns det några knep du måste lära dig för att uppnå hög genomströmning och du måste förstå konceptet med ordnad leverans av meddelanden i SSB. Jag rekommenderar dig att läsa dessa länkar:

Om sättet att upptäcka ändringar, SQL 2008 uppenbarligen lägger till nya alternativ:Ändra datainsamling och ändringsspårning . Jag betonar "tydligen", eftersom de egentligen inte är nya tekniker. CDC använder loggläsare och är baserad på de befintliga transaktionsreplikeringsmekanismerna. CT använder triggers och är mycket lik befintliga Merge-replikeringsmekanismer. De är båda avsedda för ibland anslutna system som behöver synkroniseras och därför inte lämpar sig för ändringsmeddelanden i realtid. De kan fylla i ändringstabellerna, men du har uppgiften att övervaka dessa tabeller för ändringar, vilket är exakt där du började.



  1. MySQL:fel i din SQL-syntax | GRÄNS 0, 25

  2. Välj endast rader som har en kolumn ändrad från raderna före den, med ett unikt ID

  3. Ändra ordningen på kolumner som visas i resultat, utan att ändra vald ordning

  4. Vad är en databas? Och en DBMS?