Слушатель Базы данных C#/SQL

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

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

14
задан Cœur 8 January 2019 в 12:52
поделиться

6 ответов

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

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

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

5
ответ дан 1 December 2019 в 13:21
поделиться

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

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

SQLDependention был разработан для использования в услугах ASP.NET или среднего уровня где есть относительно маленький Количество серверов, имеющих зависимости Активен против базы данных. Это было не предназначен для использования в клиенте приложения, где сотни или Тысячи клиентских компьютеров будут есть объекты SqldeCendentency для один сервер базы данных.

.

9
ответ дан 1 December 2019 в 13:21
поделиться

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

.
2
ответ дан 1 December 2019 в 13:21
поделиться

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

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

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

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

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

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

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

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

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

2
ответ дан 1 December 2019 в 13:21
поделиться

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

1
ответ дан 1 December 2019 в 13:21
поделиться

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

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

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

0
ответ дан 1 December 2019 в 13:21
поделиться
Другие вопросы по тегам:

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