Необходима помощь слушателя базы данных С#/SQL
У меня есть требование постоянно контролировать строки базы данных, чтобы проверить изменения (обновления). Если есть какие-то изменения или обновления из других источников, событие должно быть запущено в моем приложении (я использую WCF). Есть ли способ постоянно прослушивать строку базы данных для изменений?
У меня может быть больше событий для отслеживания разных строк в одной таблице. есть ли какие-либо проблемы в случае производительности. Я использую веб-службу С# для отслеживания конца SQL Server.
Ответы
Ответ 1
У меня было очень похожее требование некоторое время назад, и я решил его использовать CLR SP, чтобы вывести данные в очередь сообщений.
Чтобы облегчить развертывание, я создал CLR SP с небольшой функцией SendMessage
, которая просто нажимала сообщение в очередь сообщений и привязывала его к моим таблицам с помощью триггера AFTER INSERT (обычный триггер, а не триггер CLR).
Производительность была моей главной заботой в этом случае, но я испытывал стресс, и это сильно превзошло мои ожидания. И по сравнению с SQL Server Service Broker это очень простое решение для развертывания. Код в CLR SP действительно тривиален.
Ответ 2
Вы можете использовать триггер AFTER UPDATE в соответствующих таблицах, чтобы добавить элемент в очередь SQL Server Service Broker. Затем отправьте оповещения в очереди на веб-службу.
Еще один плакат, упомянутый SqlDependency, о котором я также подумал упоминать, но документация MSDN немного странная, поскольку он предоставляет пример клиента Windows, но также предлагает этот совет:
SqlDependency была разработана для использования в ASP.NET или службах среднего уровня где имеется относительно небольшой количество серверов, имеющих зависимости активен в отношении базы данных. это было не предназначен для использования в клиенте приложений, где сотни или тысячи клиентских компьютеров имеют объекты SqlDependency, настроенные для один сервер базы данных.
Ссылка.
Ответ 3
Мониторинг "непрерывно" может означать каждые несколько часов, минут, секунд или даже миллисекунд. Это решение может не работать для миллисекундных обновлений: но если вам нужно только "контролировать" таблицу несколько раз в минуту, вы можете просто иметь внешний процесс, проверяя таблицу на наличие обновлений. (Если присутствует столбец DateTime.) Затем вы могли обработать измененные или недавно добавленные строки и выполнить любое уведомление, которое вам нужно. Поэтому вы не будете слушать изменения, вы будете проверять их. Одно из преимуществ проведения этой проверки заключается в том, что вы не будете рисковать, если бы значительная часть производительности попала, если много строк были обновлены в течение определенного кванта времени, так как вы объединили их вместе (в отличие от ответа на каждый и каждое изменение индивидуально.)
Ответ 4
Я размышлял над идеей функции CLR или что-то вроде того, что вызывает услуга после успешного завершения вставка/обновление/удаление данных из столы. Это даже хорошо в этом ситуация?
Наверное, это не очень хорошая идея, но я думаю, это все же лучше, чем попасть в аддон.
Я предполагаю, что ваша проблема заключается в том, что вы хотите что-то сделать после каждой модификации данных, допустим, пересчитать какое-то значение или что-то еще. Ответственность за создание базы данных не является хорошей идеей, поскольку она может иметь серьезные последствия для производительности.
Вы упомянули, что хотите обнаружить вставки, обновления и удаления в разных таблицах. Выполняя это так, как вы наклоняетесь, вам потребуется настроить три триггера/функции CLR для каждой таблицы и отправить их в вашу службу WCF (это даже поддерживается в подмножестве .net, доступном внутри сервера sql?). Служба WCF принимает соответствующие действия на основе полученных событий.
Лучшим решением проблемы будет передача ответственности за обнаружение изменений данных из вашей базы данных в ваше приложение. Это действительно может быть реализовано очень легко и эффективно.
Каждая таблица имеет первичный ключ (int, GUID или что-то еще) и столбец временной метки, указывающий, когда запись была в последний раз обновлена. Это настройка, которую вы увидите очень часто в оптимистичных сценариях concurrency, поэтому может даже не понадобиться обновлять определения схемы. Хотя, если вам нужно добавить этот столбец и не может отключить обновление метки времени в приложении с помощью базы данных, вам просто нужно написать один триггер обновления для каждой таблицы, обновив отметку времени после каждого обновления.
Чтобы обнаружить изменения, ваше приложение WCF Service/Monitoring создает локальный dictionay (предпочтительно хэш-таблицу) с парами первичных ключей/временных меток за определенный промежуток времени. Используя индекс охвата в базе данных, эта операция должна быть очень быстрой. Следующим шагом будет сравнение обоих словарей и voilá, там вы идете.
Есть некоторые оговорки к этому подходу, хотя. Одна из них - это сумма записей на таблицу, другая - частота обновления (если она становится слишком низкой, она неэффективна), а еще одна точка - если вам нужен доступ к данным, предшествующим модификации/вставке.
Надеюсь, что это поможет.
Ответ 5
Почему вы не используете службу уведомления SQL Server? Я думаю, что именно то, что вы ищете. Просмотрите документацию служб уведомлений и проверьте, соответствует ли это вашим требованиям.
Ответ 6
Я думаю, здесь есть замечательные идеи; с точки зрения масштабируемости я бы сказал, что экстернализация проверки (например, ответ Пола Сасика), вероятно, самая лучшая до сих пор (+1 к нему).
Если по какой-то причине вы не хотите выполнять экстернализацию проверки, тогда другой вариант заключается в использовании HttpCache для хранения наблюдателя и обратного вызова.
Короче говоря, когда вы помещаете запись в БД, которую хотите просмотреть, вы также добавляете ее в кеш (используя метод .Add) и устанавливаете на нем SqlCacheDependency, а также обратный вызов любой логики, которую вы хотите вызов при вызове зависимостей и извлечение элемента из кеша.