Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como notificar um serviço do Windows (c #) de uma alteração de tabela de banco de dados (sql 2005)?


Você realmente não tem muitas maneiras de detectar alterações no SQL 2005. Você já listou a maioria delas.

Notificações de consulta . Esta é a tecnologia que alimenta o SqlDependency e seus derivados, você pode ler mais detalhes em A Notificação Misteriosa . Mas o QN foi projetado para invalidar resultados, não para notificar proativamente o conteúdo da alteração. Você só saberá que a tabela tem alterações, sem saber o que mudou. Em um sistema ocupado, isso não funcionará, pois as notificações virão praticamente continuamente.

Leitura de registro . É isso que a replicação transacional usa e é a maneira menos intrusiva de detectar alterações. Infelizmente só está disponível para componentes internos. Mesmo que você consiga entender o formato do log, o problema é que você precisa do suporte do mecanismo para marcar o log como 'em uso' até que você o leia, ou ele pode ser substituído. Somente a replicação transacional pode fazer esse tipo de marcação especial.

Comparação de dados . Confie nas colunas de carimbo de data/hora para detectar alterações. Também é baseado em pull, bastante intrusivo e tem problemas para detectar exclusões.

Camada de aplicativo . Essa é a melhor opção em teoria, a menos que ocorram alterações nos dados fora do escopo do aplicativo, caso em que ele desmorona. Na prática existem sempre alterações que ocorram fora do escopo do aplicativo.

Acionadores . Em última análise, esta é a única opção viável. Todos os mecanismos de mudança baseados em gatilhos funcionam da mesma forma, eles enfileiram a notificação de mudança para um componente que monitora a fila.

Sempre há sugestões para fazer uma notificação síncrona fortemente acoplada (via xp_cmdshell, xp_olecreate, CLR, notificar com WCF, você escolhe), mas todos esses esquemas falham na prática porque são fundamentalmente falhos:
- eles não conta para consistência de transação e rollbacks
- eles introduzem dependências de disponibilidade (o sistema OLTP não pode prosseguir a menos que o componente notificado esteja online)
- eles executam horrivelmente como cada operação DML tem que esperar por uma chamada RPC de alguma forma completar

Se os gatilhos não notificarem ativamente os ouvintes, mas apenas enfileirarem as notificações, há um problema no monitoramento da fila de notificações (quando digo 'fila', quero dizer qualquer tabela que atue como fila). O monitoramento implica buscar novas entradas na fila, o que significa equilibrar a frequência das verificações corretamente com a carga de alterações e reagir aos picos de carga. Isso não é nada trivial, na verdade é muito difícil. No entanto, há uma instrução no SQL Server que tem a semântica para bloquear, sem puxar, até que as alterações estejam disponíveis:WAITFOR(RECEIVE) . Isso significa Service Broker. Você mencionou o SSB várias vezes em seu post, mas está, com razão, com medo de implantá-lo por causa do grande desconhecido. Mas a realidade é que é, de longe, o mais adequado para a tarefa que você descreveu.

Você não precisa implantar uma arquitetura SSB completa, na qual a notificação é entregue até o serviço remoto (isso exigiria uma instância SQL remota de qualquer maneira, mesmo uma Express). Tudo o que você precisa fazer é desacoplar o momento em que a alteração é detectada (o gatilho DML) do momento em que a notificação é entregue (após a confirmação da alteração). Para isso, tudo o que você precisa é de uma fila SSB local e serviço. No gatilho você ENVIAR uma notificação de alteração para o serviço local. Após a confirmação da transação DML original, o procedimento de serviço é ativado e entrega a notificação, usando o CLR, por exemplo. Você pode ver um exemplo de algo semelhante a isso em Asynchronous T-SQL .

Se você seguir esse caminho, existem alguns truques que você precisará aprender para obter um alto troughput e entender o conceito de entrega ordenada de mensagens em SSB. Recomendo a leitura destes links:

Sobre os meios para detectar mudanças, SQL 2008 aparentemente adiciona novas opções:Change Data Capture and Change Tracking . Eu enfatizo 'aparentemente', já que não são tecnologias realmente novas. O CDC usa o leitor de log e é baseado nos mecanismos de replicação transacionais existentes. O CT usa gatilhos e é muito semelhante aos mecanismos de replicação de mesclagem existentes. Ambos são destinados a conectados ocasionalmente sistemas que precisam ser sincronizados e, portanto, não são adequados para notificação de alterações em tempo real. Eles podem preencher as tabelas de alterações, mas você fica com a tarefa de monitorar essas tabelas para alterações, que é exatamente de onde você começou.