Работа с уведомлениями запросов
Уведомления о запросах появились в SQL Server 2005 и SQL Server Native Client. С помощью уведомлений о запросах, построенных на основе инфраструктуры компонента Service Broker, представленной в SQL Server 2005, приложения могут получать извещения об изменениях данных. Эта функция особенно полезна для приложений, которые предоставляют кэш данных из базы данных (например, для веб-приложений), и которым требуются уведомления об изменении исходных данных.
С помощью уведомлений о запросах можно запрашивать уведомления в течение указанного времени ожидания при изменении базовых данных запроса. В запросе на уведомление указываются параметры уведомления, среди которых имя службы, текст сообщения и значение времени ожидания для сервера. Доставка уведомлений осуществляется через очередь компонента SQL Service Broker, которую приложения могут опрашивать на предмет имеющихся уведомлений.
Строка параметров уведомлений запросов имеет следующий синтаксис.
service=<service-name>[;(local database=<database> | broker instance=<broker instance>)]
Пример:
service=mySSBService;local database=mydb
Подписки на уведомления переживают процесс, который их инициирует, поскольку приложение может создать подписку на уведомление, а затем завершиться. Подписка остается действительной, а уведомление будет отправлено в случае изменения данных в течение времени ожидания, указанного при создании подписки. Уведомление определяется выполненным запросом, параметрами уведомления, а также текстом сообщения. Его можно отменить, установив нуль в качестве значения времени ожидания.
Уведомления отправляются только один раз. Чтобы получать постоянные уведомления об изменении данных, необходимо создавать новую подписку после обработки каждого уведомления путем повторного выполнения запроса.
SQL Server Native Client приложения обычно получают уведомления с помощью команды Transact-SQL RECEIVE для чтения уведомлений из очереди, связанной со службой, указанной в параметрах уведомлений.
Примечание
В запросах необходимо указывать имена таблиц, для которых требуется отправлять уведомления, например dbo.myTable
. Имена таблиц должны состоять из двух частей. Подписка будет недействительной в случае использования трех- или четырехкомпонентных имен.
Инфраструктура уведомлений основана на функции очередей, представленной в SQL Server 2005 году. Как правило, уведомления, формируемые на сервере, отправляются через эти запросы для последующей обработки.
Чтобы использовать уведомления о запросах, очередь и служба должны существовать на сервере. Их можно создать с помощью Transact-SQL следующим образом:
CREATE QUEUE myQueue
CREATE SERVICE myService ON QUEUE myQueue
([https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
Примечание
Служба должна использовать стандартный контракт https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification
, показанный выше.
Поставщик OLE DB для собственного клиента SQL Server
Поставщик SQL SERVER NATIVE CLIENT OLE DB поддерживает уведомления потребителей об изменении набора строк. Потребитель получает уведомление на каждой стадии изменения набора строк, а также при каждой попытке внести изменение.
Примечание
Передача запроса уведомлений на сервер с помощью ICommand::Execute — единственный допустимый способ подписаться на уведомления о запросах с помощью поставщика SQL Server Native Client OLE DB.
Набор свойств DBPROPSET_SQLSERVERROWSET
Чтобы поддерживать уведомления о запросах через OLE DB, SQL Server Native Client добавляет следующие новые свойства в набор свойств DBPROPSET_SQLSERVERROWSET.
Имя | Тип | Description |
---|---|---|
SSPROP_QP_NOTIFICATION_TIMEOUT | VT_UI4 | время в секундах, в течение которого уведомление запроса должно оставаться активным. Значение по умолчанию — 432000 секунд (5 дней). Минимальное значение — 1 секунда, а максимальное значение — 2^31-1 секунд. |
SSPROP_QP_NOTIFICATION_MSGTEXT | VT_BSTR | Текст сообщения уведомления. Определяется пользователем и не имеет стандартного формата. По умолчанию эта строка пуста. В сообщении можно использовать от 1 до 2000 символов. |
SSPROP_QP_NOTIFICATION_OPTIONS | VT_BSTR | параметры уведомлений о запросах. Эти параметры указываются в строке с использованием синтаксиса имя=значение. За создание службы и считывание уведомлений из очереди отвечает пользователь. Значением по умолчанию является пустая строка. |
Подписка на уведомления всегда фиксируется независимо от того, выполнялась ли инструкция в рамках пользовательской транзакции или в режиме AUTO COMMIT, а также была ли транзакция, в рамках которой выполнялась инструкция, зафиксирована либо был выполнен ее откат. Уведомление сервера срабатывает при возникновении любого из следующих недопустимых условий: изменение базовых данных или схемы либо по истечении времени ожидания, в зависимости от того, что произойдет первым. Регистрации уведомлений удаляются сразу же после их срабатывания. Поэтому, если приложению требуется получение уведомлений в дальнейшем, оно должно подписаться на них снова сразу после получения уведомления.
Другое соединение или поток может проверять целевую очередь на наличие уведомлений. Пример:
WAITFOR (RECEIVE * FROM MyQueue); // Where MyQueue is the queue name.
Следует отметить, что инструкция SELECT * не удаляет какие-либо записи из очереди, а инструкция RECEIVE * FROM удаляет. Если очередь пуста, поток сервера будет остановлен. При наличии в очереди записей в момент вызова они возвращаются мгновенно; в противном случае вызов ожидает появления записи в очереди.
RECEIVE * FROM MyQueue
Если очередь пуста, то эта инструкция немедленно возвращает пустой результирующий набор; в противном случае она возвращает все уведомления в очереди.
Если значение свойств SSPROP_QP_NOTIFICATION_MSGTEXT и SSPROP_QP_NOTIFICATION_OPTIONS не равно NULL и не является пустым, то при каждом выполнении этой команды на сервер отправляется заголовок потока табличных данных уведомлений о запросах, содержащий три свойства, указанные выше. Если значение любого из них равно NULL (или пустое), заголовок не отправляется, а формируется DB_E_ERRORSOCCURRED (или DB_S_ERRORSOCCURRED, если оба свойства обозначены, как необязательные), а значение состояния устанавливается в DBPROPSTATUS_BADVALUE. Поверка выполняется в случае команды Execute/Prepare. Аналогичным образом, DB_S_ERRORSOCCURED возникает, когда свойства уведомления о запросе задаются для подключений к SQL Server версиям до SQL Server 2005. В этом случае значение состояния — DBPROPSTATUS_NOTSUPPORTED.
Запуск подписки не гарантирует успешной доставки последующих сообщений. Кроме того, допустимость указанного имени службы также не проверяется.
Примечание
При подготовке инструкций подписка никогда не запускается. Запуск подписки происходит только при выполнении инструкций, а использование базовых служб OLE DB не оказывает влияния на уведомления о запросах.
Дополнительные сведения о наборе свойств DBPROPSET_SQLSERVERROWSET см. в разделе Свойства и поведение набора строк.
Драйвер ODBC для собственного клиента SQL Server
Драйвер SQL SERVER NATIVE CLIENT ODBC поддерживает уведомления о запросах за счет добавления трех новых атрибутов к функциям SQLGetStmtAttr и SQLSetStmtAttr:
Атрибут SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT
SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS
SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT
Если значение свойств SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT и SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS не равно NULL, то при каждом выполнении этой команды на сервер отправляется заголовок потока табличных данных уведомлений о запросах, содержащий три атрибута, указанных выше. Если значение любого из них равно NULL, заголовок не отправляется и возвращается SQL_SUCCESS_WITH_INFO. Проверка выполняется в функциях SQLPrepare, SqlExecDirect и SqlExecute, которые завершаются ошибкой, если атрибуты недопустимы. Аналогичным образом, если эти атрибуты уведомления о запросах заданы для версий SQL Server до SQL Server 2005, выполнение завершается сбоем с SQL_SUCCESS_WITH_INFO.
Примечание
Подготовка инструкций никогда не вызывает запуска подписки; подписка может быть запущена выполнением инструкции.
Особые случаи и ограничения
Следующие типы данных для уведомлений не поддерживаются:
text
ntext
image
Если сделан запрос на уведомление о запросе, который возвращает один из этих типов данных, уведомление срабатывает мгновенно с указанием, что выполнить подписку на уведомление невозможно.
Если запрос на подписку сделан для пакета или хранимой процедуры, для каждой инструкции, выполняемой в пакете или хранимой процедуре, будет сделан отдельный запрос на подписку. Инструкция EXECUTE не регистрирует уведомление, но направляет требование об уведомлении выполняемой команде. Если это пакет, к выполняемым инструкциям будет применен контекст и правила, описанные выше.
Отправка запроса на уведомление, отправленное тем же пользователем в том же контексте базы данных и имеющего тот же шаблон, те же значения параметров, тот же идентификатор уведомления и то же расположение доставки существующей активной подписки, продлевает существующую подписку, сбрасывая новое указанное время ожидания. Это означает, что если для идентичных запросов запрашивается уведомление, будет отправлено только одно уведомление. Данные условия применяются к запросам, повторяющимся в пакетах, или к запросам, которые вызываются несколько раз в хранимой процедуре.