sql >> Database teknologi >  >> RDS >> Sqlserver

Hvordan underretter man en Windows-tjeneste(c#) om en DB-tabelændring (sql 2005)?

Du har virkelig ikke så mange måder at opdage ændringer i SQL 2005. Du har allerede nævnt de fleste af dem.

Forespørgselsmeddelelser . Dette er teknologien, der driver SqlDependency og dets derivater. Du kan læse flere detaljer på Den mystiske notifikation . Men QN er designet til at ugyldiggøre resultater, ikke for proaktivt at give besked om ændring af indhold. Du vil kun vide, at tabellen har ændringer, uden at vide, hvad der er ændret. På et travlt system vil dette ikke virke, da meddelelserne vil komme stort set konstant.

Loglæsning . Dette er, hvad transaktionsreplikering bruger og er den mindst påtrængende måde at opdage ændringer på. Er desværre kun tilgængelig for interne komponenter. Selvom det lykkes dig at forstå logformatet, er problemet, at du har brug for support fra motoren til at markere loggen som 'i brug', indtil du læser den, eller den kan blive overskrevet. Kun transaktionsreplikering kan udføre denne form for speciel mærkning.

Datasammenligning . Stol på tidsstempelkolonner for at registrere ændringer. Er også pull-baseret, ret påtrængende og har problemer med at opdage sletninger.

Applikationslag . Dette er den bedste mulighed i teorien, medmindre der sker ændringer i dataene uden for applikationens omfang, i hvilket tilfælde det smuldrer. I praksis er der altid ændringer, der sker uden for applikationens omfang.

Udløsere . I sidste ende er dette den eneste levedygtige mulighed. Alle ændringsmekanismer baseret på triggere fungerer på samme måde, de sætter ændringsmeddelelsen i kø til en komponent, der overvåger køen.

Der er altid forslag om at lave en tæt koblet, synkron notifikation (via xp_cmdshell, xp_olecreate, CLR, notify med WCF, you name it), men alle disse ordninger mislykkes i praksis, fordi de er grundlæggende fejlbehæftede:
- de gør det ikke tager højde for transaktionskonsistens og rollbacks
- de indfører tilgængelighedsafhængigheder (OLTP-systemet kan ikke fortsætte, medmindre den notificerede komponent er online)
- de udfører forfærdeligt, da hver DML-operation skal vente på et RPC-kald af en eller anden form at fuldføre

Hvis triggerne faktisk ikke aktivt giver lytterne besked, men kun stiller notifikationerne i kø, er der et problem med at overvåge notifikationskøen (når jeg siger 'kø', mener jeg enhver tabel, der fungerer som en kø). Overvågning indebærer at trække efter nye poster i køen, hvilket betyder at balancere hyppigheden af ​​kontroller korrekt med belastningen af ​​ændringer og reagere på belastningsspidser. Dette er slet ikke trivielt, det er faktisk meget svært. Der er dog én sætning i SQL-serveren, der har semantikken til at blokere, uden at trække, indtil ændringer bliver tilgængelige:WAITFOR(RECEIVE) . Det betyder Servicemægler. Du nævnte SSB flere gange i dit indlæg, men du er med rette bange for at implementere det på grund af det store ukendte. Men virkeligheden er, at det langt hen ad vejen passer bedst til den opgave, du beskrev.

Du behøver ikke at implementere en fuld SSB-arkitektur, hvor meddelelsen leveres hele vejen til fjerntjenesten (det ville alligevel kræve en ekstern SQL-instans, selv en Express). Det eneste, du skal medvirke til, er at afkoble det øjeblik, hvor ændringen detekteres (DML-udløseren) fra det øjeblik, hvor meddelelsen afgives (efter ændringen er begået). Til dette behøver du kun en lokal SSB-kø og service. I triggeren SEND en ændringsmeddelelse til den lokale tjeneste. Efter den oprindelige DML-transaktion er forpligtet, aktiveres og leverer meddelelsen, f.eks. ved hjælp af CLR. Du kan se et eksempel på noget lignende dette på Asynchronous T-SQL .

Hvis du går ned ad den vej, er der nogle tricks, du skal lære for at opnå høj troughput, og du skal forstå konceptet med bestilt levering af beskeder i SSB. Jeg anbefaler dig at læse disse links:

Om midlerne til at opdage ændringer, SQL 2008 tilsyneladende tilføjer nye muligheder:Skift datafangst og ændringssporing . Jeg understreger 'tilsyneladende', da de ikke rigtig er nye teknologier. CDC bruger loglæser og er baseret på de eksisterende Transaktionelle replikeringsmekanismer. CT bruger triggere og ligner meget eksisterende Merge-replikeringsmekanismer. De er begge beregnet til af og til forbundet systemer, der skal synkroniseres og derfor ikke er passende for ændringsmeddelelse i realtid. De kan udfylde ændringstabellerne, men du står tilbage med opgaven at overvåge disse tabeller for ændringer, hvilket er præcis fra det sted, hvor du startede.



  1. Hvordan gemmer man en datatabel i databasen?

  2. Sådan fungerer SQLite Avg()

  3. bundle exec rake assets:precompile - databasekonfiguration specificerer ikke adapter

  4. Optimal MySQL-konfiguration (my.cnf)