Как уведомить сервис окон (c#) Изменения Таблицы базы данных (sql 2005)?

SmartSVN, SmartCVS

16
задан Mike Tours 13 October 2009 в 13:33
поделиться

5 ответов

У вас действительно не так много способов обнаружить изменения в SQL 2005. Вы уже перечислили большинство из них.

Уведомления о запросах . Это технология, на которой работает SqlDependency и ее производные, вы можете прочитать более подробную информацию в The Mysterious Notification . Но QN предназначен для аннулирования результатов, а не для упреждающего уведомления об изменении содержимого. Вы будете знать только то, что в таблице есть изменения, не зная, что изменилось. В загруженной системе это не сработает, поскольку уведомления будут приходить постоянно.

Чтение журнала . Это то, что использует репликация транзакций, и это наименее навязчивый способ обнаружения изменений. К сожалению, доступно только для внутренних компонентов. Даже если вам удастся понять формат журнала, проблема в том, что вам нужна поддержка движка, чтобы пометить журнал как «используемый», пока вы его не прочтете, иначе он может быть перезаписан. Только репликация транзакций может делать такую ​​специальную маркировку.

Сравнение данных . Полагайтесь на столбцы с отметками времени для обнаружения изменений. Также основан на вытягивании, довольно навязчив и имеет проблемы с обнаружением удалений.

Уровень приложения . Теоретически это лучший вариант, если только в данных не происходят изменения, выходящие за рамки приложения, и в этом случае он рассыпается. На практике всегда есть изменения, выходящие за рамки приложения.

Триггеры . В конце концов, это единственный жизнеспособный вариант. Все механизмы изменения, основанные на триггерах, работают одинаково: они помещают уведомление об изменении в очередь компоненту, который контролирует очередь. - они не учитывают согласованность транзакций и откаты
- они вводят зависимости доступности (система OLTP не может работать, если уведомленный компонент не подключен к сети)
- они работают ужасно, так как каждая операция DML должна ждать завершения вызова RPC некоторой формы

Если триггеры фактически не уведомляют слушателей, а только ставят уведомления в очередь, существует проблема с мониторингом очереди уведомлений (когда я говорю «очередь», я имею в виду любую таблицу, которая действует как очередь). Мониторинг подразумевает поиск новых записей в очереди, что означает правильную балансировку частоты проверок с загрузкой изменений и реакцию на скачки нагрузки. Это совсем нетривиально, на самом деле очень сложно. Однако в SQL-сервере есть один оператор, семантика которого блокируется без извлечения, пока изменения не станут доступны: WAITFOR (RECEIVE) . Это означает Service Broker. Вы несколько раз упомянули SSB в своем посте, но вы правильно сделали, боится развертывать его из-за большого неизвестного. Но реальность такова, что он, безусловно, лучше всего подходит для описанной вами задачи.

Вам не нужно развертывать полную архитектуру SSB, при которой уведомление доставляется полностью удаленной службе (для этого потребуется в любом случае удаленный экземпляр SQL, даже Express). Все, что вам нужно соучастником, - это отделить момент обнаружения изменения (триггер DML) от момента доставки уведомления (после того, как изменение было зафиксировано). Для этого все, что вам нужно, это локальная очередь SSB и сервис. В триггере вы ОТПРАВЛЯЕТЕ уведомление об изменении в локальную службу. После фиксации исходной транзакции DML служебная процедура активирует и доставляет уведомление, например, с использованием CLR. Вы можете увидеть пример чего-то похожего на Асинхронный T-SQL .

Если вы пойдете по этому пути, вам нужно будет изучить некоторые приемы для достижения высокой пропускной способности, и вы должны понимать концепция упорядоченной доставки сообщений в SSB. Я рекомендую вам прочитать эти ссылки:

Что касается средств обнаружения изменений, SQL 2008 , по-видимому, добавляет новые параметры: Сбор и отслеживание изменений данных . Я подчеркиваю «очевидно», поскольку это не совсем новые технологии. CDC использует средство чтения журналов и основано на существующих механизмах репликации транзакций. CT использует триггеры и очень похож на существующие механизмы репликации слиянием. Оба они предназначены для периодически подключаемых систем, которые нуждаются в синхронизации и, следовательно, не подходят для уведомления об изменениях в реальном времени. Они могут заполнять таблицы изменений, но вам остается следить за изменениями в этих таблицах, и именно с этого вы начали.

19
ответ дан 30 November 2019 в 22:31
поделиться

Это можно было сделать разными способами. приведенный ниже метод прост, поскольку вы не хотите использовать триггеры CLR и параметры sqlcmd.

  • Вместо использования триггеров CLR вы можете создать обычный триггер вставки, который обновляет выделенную таблицу отслеживания при каждой вставке.

  • И разработать специальный оконный сервис, который активно опрашивает таблицу отслеживания и обновляет удаленную службу, если есть какие-либо изменения в данных, и устанавливает статус в таблице отслеживания как «Готово» (чтобы он больше не выбирался).

РЕДАКТИРОВАТЬ:

Я думаю, что Microsoft sync сервисы для ADO.Net могут работать на вас. Ознакомьтесь с приведенными ниже ссылками. Это может помочь вам

1
ответ дан 30 November 2019 в 22:31
поделиться

В аналогичных обстоятельствах мы используем триггер CLR, который записывает сообщения в очередь (MSMQ). Сервис, написанный на C #, отслеживает очередь и выполняет постобработку. В нашем случае все это делается на одном сервере, но вы можете отправлять эти сообщения прямо в удаленную очередь на другой компьютер, полностью минуя «локального слушателя».

Код, вызываемый из триггера, выглядит следующим образом:

public static void SendMsmqMessage(string queueName, string data)
{
    //Define the queue path based on the input parameter.
    string QueuePath = String.Format(".\\private$\\{0}", queueName);

    try
    {
        if (!MessageQueue.Exists(QueuePath))
            MessageQueue.Create(QueuePath);

        //Open the queue with the Send access mode
        MessageQueue MSMQueue = new MessageQueue(QueuePath, QueueAccessMode.Send);

        //Define the queue message formatting and create message
        BinaryMessageFormatter MessageFormatter = new BinaryMessageFormatter();
        Message MSMQMessage = new Message(data, MessageFormatter);

        MSMQueue.Send(MSMQMessage);
    }
    catch (Exception x)
    {
        // async logging: gotta return from the trigger ASAP
        System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(LogException), x);
    }
}
0
ответ дан 30 November 2019 в 22:31
поделиться

Поскольку вы сказали, что в этой таблице выполняется много операций вставки, пакетная обработка может подойти лучше.

Зачем просто создать запланированное задание, которое обрабатывает новые данные, идентифицированные столбцом флагов , и обрабатывать данные большими порциями?

-1
ответ дан 30 November 2019 в 22:31
поделиться

Используйте стандартный триггер для запуска CLR в базе данных. Эта среда CLR будет запускать программу только удаленно с использованием класса Win32_Process:

http://motevich.blogspot.com/2007/11/execute-program-on-remote-computer.html

-1
ответ дан 30 November 2019 в 22:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: