Слушатель базы данных C # / SQL - PullRequest
14 голосов
/ 28 января 2010

У меня есть требование постоянно отслеживать строки базы данных, чтобы проверять наличие изменений (обновлений). Если есть какие-либо изменения или обновления из других источников, событие должно быть запущено в моем приложении (я использую WCF). Есть ли способ непрерывного прослушивания строки базы данных на предмет изменений?

У меня может быть больше событий для отслеживания разных строк в одной и той же таблице. есть ли проблемы в случае производительности. Я использую веб-сервис C # для мониторинга серверной части SQL Server.

Ответы [ 6 ]

9 голосов
/ 28 января 2010

Вы можете использовать триггер AFTER UPDATE для соответствующих таблиц, чтобы добавить элемент в очередь SQL Server Service Broker . Затем отправьте уведомления в очередь на ваш веб-сервис.

В другом плакате упоминается SqlDependency, о котором я также думал упомянуть, но документация MSDN немного странная в том смысле, что она содержит пример клиента Windows, но также предлагает такой совет:

SqlDependency был разработан для использования в ASP.NET или сервисах среднего уровня где есть относительно маленький количество серверов, имеющих зависимости активен в отношении базы данных. это было не предназначен для использования в клиенте приложения, где сотни или тысячи клиентских компьютеров будут иметь объекты SqlDependency, настроенные для один сервер базы данных.

1012 * Ref *.

5 голосов
/ 27 февраля 2010

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

Чтобы упростить развертывание, я создал CLR SP с крошечной маленькой функцией SendMessage, которая просто помещала сообщение в очередь сообщений, и привязал его к моим таблицам, используя триггер AFTER INSERT (обычный триггер, а не триггер CLR ).

Производительность была моей главной заботой в этом случае, но я провел стресс-тестирование, и оно значительно превзошло мои ожидания. И по сравнению с SQL Server Service Broker это очень простое в развертывании решение. Код в CLR SP действительно тривиален.

2 голосов
/ 23 февраля 2010

Я обдумал идею функции CLR или что-то в этом роде сервис после успешно вставка / обновление / удаление данных из столы. Это даже хорошо в этом ситуация?

Вероятно, это не очень хорошая идея, но я думаю, что это все же лучше, чем попасть в ад триггеров таблицы.

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

Вы упомянули, что хотите обнаруживать вставки, обновления и удаления в разных таблицах. Делая это так, как вы к этому склоняетесь, для этого потребуется настроить три триггера / функции CLR для каждой таблицы и заставить их публиковать событие в вашей службе WCF (это даже поддерживается в подмножестве .net, доступном на сервере SQL?). Служба WCF выполняет соответствующие действия в зависимости от полученных событий.

Лучшим решением проблемы было бы перенести ответственность за обнаружение модификации данных из вашей базы данных в ваше приложение. Это на самом деле может быть реализовано очень легко и эффективно.

Каждая таблица имеет первичный ключ (int, GUID или любой другой) и столбец отметки времени, указывающий, когда запись в последний раз обновлялась. Эту настройку вы увидите очень часто в сценариях оптимистичного параллелизма, поэтому может даже не потребоваться обновлять определения вашей схемы. Однако, если вам нужно добавить этот столбец и вы не можете разгрузить обновление отметки времени для приложения, использующего базу данных, вам просто нужно написать один триггер обновления для таблицы, обновляя отметку времени после каждого обновления.

Для обнаружения изменений приложение WCF Service / Monitoring создает локальный словарь (желательно хеш-таблицу) с парами первичный ключ / временная метка в заданный интервал времени. Используя индекс покрытия в базе данных, эта операция должна быть очень быстрой. Следующим шагом будет сравнение словарей и вуаля, вот и все.

Однако есть некоторые предостережения в отношении этого подхода. Один из них - это сумма записей на таблицу, другой - частота обновления (если она становится слишком низкой, это неэффективно), и еще одно точное определение - если вам нужен доступ к данным до изменения / вставки.

Надеюсь, это поможет.

2 голосов
/ 21 февраля 2010

Мониторинг «непрерывно» может означать каждые несколько часов, минут, секунд или даже миллисекунд. Это решение может не работать для обновлений в миллисекундах: но если вам нужно «контролировать» таблицу только несколько раз в минуту, вы можете просто попросить внешний процесс проверить таблицу на наличие обновлений. (Если присутствует столбец DateTime.) Затем можно обработать измененные или вновь добавленные строки и выполнить любое необходимое уведомление. Таким образом, вы не будете прислушиваться к изменениям, вы будете проверять их. Одним из преимуществ такой проверки будет то, что вы не рискуете сильно снизить производительность, если много строк было обновлено в течение заданного периода времени, поскольку вы объединяете их вместе (в отличие от ответа на каждый и каждое изменение индивидуально.)

1 голос
/ 24 февраля 2010

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

0 голосов
/ 26 февраля 2010

Я думаю, что здесь есть отличные идеи; с точки зрения масштабируемости, я бы сказал, что экстернализация чека (например, ответ Пола Сасика) является, вероятно, лучшей на данный момент (+1 для него).

Если по какой-то причине вы не хотите выводить проверку извне, то другим вариантом будет использование HttpCache для хранения наблюдателя и обратного вызова.

Короче говоря, когда вы помещаете запись в БД, которую хотите просмотреть, вы также добавляете ее в кеш (с помощью метода .Add) и устанавливаете для нее SqlCacheDependency, а также выполняете обратный вызов любой логики, которую хотите вызывать, когда вызывается зависимость и элемент извлекается из кэша.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...