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

Come notificare a un servizio Windows (c#) una modifica della tabella DB (sql 2005)?

Non hai davvero molti modi per rilevare le modifiche in SQL 2005. Ne hai già elencate la maggior parte.

Notifiche di query . Questa è la tecnologia che alimenta SqlDependency e i suoi derivati, puoi leggere maggiori dettagli su La misteriosa notifica . Ma QN è progettato per invalidare risultati, di non notificare in modo proattivo il contenuto delle modifiche. Saprai solo che la tabella ha delle modifiche, senza sapere cosa è cambiato. Su un sistema occupato questo non funzionerà, poiché le notifiche arriveranno praticamente continuamente.

Lettura registro . Questo è ciò che utilizza la replica transazionale ed è il modo meno intrusivo per rilevare le modifiche. Purtroppo è disponibile solo per i componenti interni. Anche se riesci a capire il formato del registro, il problema è che hai bisogno del supporto del motore per contrassegnare il registro come "in uso" fino a quando non lo leggi, altrimenti potrebbe essere sovrascritto. Solo la replica transazionale può eseguire questo tipo di contrassegno speciale.

Confronto dati . Affidati alle colonne timestamp per rilevare le modifiche. È anche basato su pull, abbastanza invadente e ha problemi a rilevare le eliminazioni.

Livello applicazione . Questa è l'opzione migliore in teoria, a meno che non si verifichino modifiche ai dati al di fuori dell'ambito dell'applicazione, nel qual caso si sgretola. In pratica ci sono sempre modifiche che si verificano al di fuori dell'ambito dell'applicazione.

Trigger . In definitiva, questa è l'unica opzione praticabile. Tutti i meccanismi di modifica basati sui trigger funzionano allo stesso modo, accodano la notifica di modifica a un componente che monitora la coda.

Ci sono sempre suggerimenti per eseguire una notifica sincrona strettamente accoppiata (tramite xp_cmdshell, xp_olecreate, CLR, notifica con WCF, lo chiami), ma tutti questi schemi falliscono nella pratica perché sono fondamentalmente imperfetti:
- non lo fanno tengono conto della coerenza delle transazioni e dei rollback
- introducono dipendenze di disponibilità (il sistema OLTP non può procedere a meno che il componente notificato non sia online)
- si comportano in modo orribile poiché ogni operazione DML deve attendere una chiamata RPC di qualche forma per completare

Se i trigger in realtà non notificano attivamente gli ascoltatori, ma accodano solo le notifiche, c'è un problema nel monitoraggio della coda delle notifiche (quando dico "coda", intendo qualsiasi tabella che funge da coda). Il monitoraggio implica l'estrazione di nuove voci nella coda, il che significa bilanciare correttamente la frequenza dei controlli con il carico delle modifiche e reagire ai picchi di carico. Non è affatto banale, anzi è molto difficile. Tuttavia, esiste un'istruzione nel server SQL che ha la semantica per bloccare, senza eseguire il pull, fino a quando le modifiche non diventano disponibili:WAITFOR(RICEIVE) . Ciò significa Service Broker. Hai menzionato più volte SSB nel tuo post, ma hai, giustamente, paura di schierarlo a causa della grande incognita. Ma la realtà è che è, di gran lunga, la soluzione migliore per il compito che hai descritto.

Non è necessario distribuire un'architettura SSB completa, in cui la notifica viene consegnata fino al servizio remoto (che richiederebbe comunque un'istanza SQL remota, anche Express). Tutto ciò che devi complice è disaccoppiare il momento in cui viene rilevata la modifica (il trigger DML) dal momento in cui viene consegnata la notifica (dopo che la modifica è stata confermata). Per questo tutto ciò di cui hai bisogno è una coda e un servizio SSB locali. Nel trigger INVIA una notifica di modifica al servizio locale. Dopo il commit della transazione DML originale, la procedura di servizio si attiva e fornisce la notifica, ad esempio utilizzando CLR. Puoi vedere un esempio di qualcosa di simile a T-SQL asincrono .

Se percorri quella strada, devi imparare alcuni trucchi per ottenere un rendimento elevato e devi comprendere il concetto di consegna ordinata dei messaggi in SSB. Ti consiglio di leggere questi link:

Informazioni sui mezzi per rilevare le modifiche, SQL 2008 apparentemente aggiunge nuove opzioni:Change Data Capture e Change Tracking . Sottolineo 'apparentemente', dal momento che non sono proprio nuove tecnologie. CDC utilizza il lettore di log e si basa sui meccanismi di replica transazionale esistenti. La TC utilizza trigger ed è molto simile ai meccanismi di replicazione Merge esistenti. Sono entrambi destinati a collegati occasionalmente sistemi che devono sincronizzarsi e quindi non sono appropriati per la notifica delle modifiche in tempo reale. Possono popolare le tabelle delle modifiche, ma ti rimane il compito di monitorare queste tabelle per le modifiche, che è esattamente da dove hai iniziato.