Подтвердить что ты не робот

Каковы ограничения SqlDependency

Я использую таблицу в качестве очереди сообщений и "подписываюсь" на получение обновлений с помощью SqlDependency. Везде, где я читаю, люди говорят, что следите за ограничениями, но конкретно не говорите, что они есть. Из того, что я понял, у вас будут проблемы, когда таблица будет иметь очень высокую частоту обновления, к счастью, я смотрю только на 10 - 20 значений в минуту максимум.

Каковы другие ограничения/влияние на SqlServer?

4b9b3361

Ответ 1

Наиболее полный список, который я могу найти (отсюда), выглядит следующим образом:

  • Проецируемые столбцы в операторе SELECT должны быть указаны явно, а имена таблиц должны содержать имена из двух частей. Обратите внимание, что это означает, что все таблицы, на которые есть ссылки в операторе, должны находиться в одной базе данных.
  • Оператор не может использовать звездочку() или имя_таблицы. синтаксис для указания столбцов.
  • Оператор не может использовать безымянные столбцы или повторяющиеся имена столбцов.
  • Оператор должен ссылаться на базовую таблицу.
  • Оператор не должен ссылаться на таблицы с вычисляемыми столбцами.
  • Проецируемые столбцы в операторе SELECT могут не содержать агрегатных выражений, если только оператор не использует выражение GROUP BY. Когда предоставляется выражение GROUP BY, список выбора может содержать агрегатные функции COUNT_BIG() или SUM(). Тем не менее, SUM() не может быть указан для столбца, допускающего значение NULL. Оператор не может указывать HAVING, CUBE или ROLLUP.
  • Проецируемый столбец в операторе SELECT, который используется как простое выражение, не должен появляться более одного раза.
  • Оператор не должен включать операторов PIVOT или UNPIVOT.
  • Оператор не должен включать операторы UNION, INTERSECT или EXCEPT.
  • Заявление не должно ссылаться на представление.
  • Оператор не должен содержать ничего из следующего: DISTINCT, COMPUTE или COMPUTE BY или INTO.
  • Оператор не должен ссылаться на глобальные переменные сервера (@@variable_name).
  • Оператор не должен ссылаться на производные таблицы, временные таблицы или переменные таблиц.
  • Оператор не должен ссылаться на таблицы или представления из других баз данных или серверов.
  • Оператор не должен содержать подзапросов, внешних объединений или самостоятельных объединений.
  • Оператор не должен ссылаться на большие типы объектов: текст, текст и изображение.
  • Оператор не должен использовать полнотекстовые предикаты CONTAINS или FREETEXT.
  • Оператор не должен использовать функции набора строк, включая OPENROWSET и OPENQUERY.
  • Оператор не должен использовать ни одну из следующих агрегатных функций: AVG, COUNT (*), MAX, MIN, STDEV, STDEVP, VAR или VARP.
  • Оператор не должен использовать никаких недетерминированных функций, включая функции ранжирования и управления окнами.
  • Оператор не должен содержать определенные пользователем агрегаты.
  • Оператор не должен ссылаться на системные таблицы или представления, включая представления каталога и представления динамического управления.
  • Заявление не должно включать информацию FOR BROWSE.
  • Оператор не должен ссылаться на очередь.
  • Оператор не должен содержать условных операторов, которые не могут изменяться и не могут возвращать результаты (например, WHERE 1 = 0).
  • Оператор не может указывать подсказку блокировки READPAST.
  • Заявление не должно ссылаться на QUEUE компонента Service Broker.
  • Заявление не должно ссылаться на синонимы.
  • Оператор не должен иметь сравнения или выражения, основанного на двойных/реальных типах данных.
  • Оператор не должен использовать выражение TOP.

Дополнительные ссылки:

Ответ 2

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

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

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

Ответ 3

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

Например, этот select отлично работает в SQL Management Studio:

select [MyColumn] from [MyDatabase].[MySchema].[MyTable]

Однако это отклоняется SQL Service Broker, потому что мы ссылаемся на базу данных в инструкции select, а обратный вызов из SqlDependency возвращается с Invalid в SqlNotificationEventArgs e, см. http://msdn.microsoft.com/en-us/library/ms189308.aspx.

Изменение SQL, переданного в SqlDependency, в следующее выражение устраняет ошибку:

select [MyColumn] from [MySchema].[MyTable]

Update

Приведенный выше пример является лишь одним из многих, многих ограничений для оператора SQL, от которого зависит SQL Service Broker. Полный список ограничений см. В Каковы ограничения SqlDependency.

Причина? Оператор SQL, используемый SQL Service Broker, преобразуется за кулисами в инструкции для мониторинга журнала транзакций SQL для внесения изменений в базу данных. Этот мониторинг выполняется в ядре SQL Server, что делает его чрезвычайно быстрым, когда дело доходит до обнаружения изменений в таблице (таблицах). Однако эта скорость стоит дорого: вы не можете использовать только какой-либо оператор SQL, вы должны использовать тот, который может быть преобразован в инструкции для мониторинга SQL Transaction Войти.

Ответ 4

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

with (NOLOCK) 

Это не упоминается в документации (насколько я могу судить)

Перед процедурой script

требуются следующие параметры SET:
SET ANSI_NULLS ON
SET ANSI_PADDING ON  
SET ANSI_WARNINGS ON

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

SET CONCAT_NULL_YIELDS_NULL ON 
SET QUOTED_IDENTIFIER ON 
SET NUMERIC_ROUNDABORT OFF 
SET ARITHABORT ON

Ответ 5

Еще одна большая проблема, с которой я сталкиваюсь с этой технологией: необходимость подключения к подписчику для разрешения "Создать процедуру". Уровень веб-службы моего приложения на данный момент работает как ограниченный пользователь. Чтобы получить настройку уведомлений с помощью SQLDependency, мне нужно было бы открыть этого пользователя для создания proc. Похоже, что это довольно хороший шаг по пути владения.

Ответ 6

Чтобы преодолеть эти ограничения, вы можете попробовать использовать SqlTableDependency. Посмотрите на www.sqltabledependency.it

Ответ 7

Он использует Service Broker. Поэтому он не будет работать на неуправляемых экземплярах SQL Azure. Так что будьте осторожны, если вы используете SQL Azure или когда-либо может.

https://docs.microsoft.com/en-us/azure/sql-database/sql-database-features

Сервисный Брокер

Поддерживается отдельными базами данных и эластичными пулами:

нет

Поддерживается управляемыми экземплярами:

Да, но только в рамках инстанса. См. Различия сервисного брокера

Так что, вероятно, не подходит, если только ваша среда не может его использовать!