Использование объекта SqlNotificationRequest для подписки на уведомления о запросах

Подписка на уведомления о запросах с использованием SqlNotificationRequest требует подготовки базовых объектов компонента Service Broker до того, как приложение сможет запросить уведомление. Как только пользователь запрашивает подписку, его приложение начинает контролировать очередь на сообщение уведомления, и при появлении сообщения соответствующим образом реагирует на него.

SQL Server доставляет уведомления о запросах при помощи компонента Service Broker. Сообщение уведомления о запросе имеет имя типа сообщения https://schemas.microsoft.com/SQL/Notifications/QueryNotification. Компонент Service Broker проверяет сообщения этого типа как VALID_XML WITH SCHEMA COLLECTION. Для подписок, созданных с помощью объекта SqlNotificationRequest, приложение отвечает за мониторинг очереди и обработку сообщений уведомления. Поэтому, использование объекта SqlNotificationRequest обязательно предполагает выполнение внешнего приложения. Этот подраздел содержит сведения, касающиеся шагов, выполняющихся для подписки на уведомления о запросах с использованием объекта SqlNotificationRequest. Дополнительные сведения о создании приложения, обрабатывающего сообщения уведомлений о запросах, см. в разделе Преимущества программирования с компонентом Service Broker.

Объект SqlNotificationRequest должен указать службу, которая получает сообщения уведомлений. Чтобы создать службу, необходимо создать очередь для используемой службы, а затем создать службу. Также необходимо создать маршрут к службе в локальной базе данных.

Компонент Database Engine использует контракт https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification для отправки сообщений уведомлений, так что создаваемая служба должна принимать диалоги, которые придерживаются этого контракта. В нижеследующем примере создается служба с именем WebCacheNotifications, которая использует очередь WebCacheMessages, а затем в локальной базе данных создается маршрут к службе WebCacheNotifications в локальной базе данных.

USE AdventureWorks2008R2 ;

CREATE QUEUE WebSiteCacheMessages ;

CREATE SERVICE WebCacheNotifications
  ON QUEUE WebSiteCacheMessages
  ([https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]) ;

CREATE ROUTE
  WebCacheMessagesRoute
  WITH SERVICE_NAME = 'WebCacheNotifications',
       ADDRESS = 'LOCAL' ;

Контракт https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification указывает, что сообщения типа https://schemas.microsoft.com/SQL/Notifications/QueryNotification могут отправляться инициатором диалога.

Именем службы в объекте SqlNotificationRequest является имя службы компонента Service Broker. Уведомление создается как сообщение компонента Service Broker.

Запрос уведомления должен также содержать строку сообщения для запроса. Когда компонент Database Engine создает уведомление для этого запроса, сообщение уведомления содержит строку сообщения. Сообщение уведомления является XML-документом. В этом документе содержится элемент Message, в котором хранится строка сообщения, которая входит в запрос уведомления. Приложение использует строку сообщения для идентификации запроса, который соответствует уведомлению.

Управление подписками на уведомления осуществляется с помощью сочетаний запросов и сообщений. Если приложение запрашивает другое уведомление с тем же сообщением или тем же запросом, компонент Database Engine обновляет существующую подписку на уведомление, не создавая новую подписку. Строка сообщения может быть любой. Обратите внимание, что компонент Database Engine определяет, являются ли два сообщения одинаковыми. Поэтому в зависимости от параметров, установленных для строк базы данных, они могут быть не эквивалентны в программе, но эквивалентны в базе данных. Например, компонент Database Engine рассматривает строки, отличающиеся только числом конечных пробелов, одинаковыми.

В следующем примере приведена простая программа, в которой создается подписка на уведомление с помощью объекта SqlNotificationRequest:

[Visual Basic]

Option Strict On

Imports System
Imports System.Data
Imports System.Data.Sql
Imports System.Data.SqlClient


Namespace Microsoft.Samples.SqlServer

Module NotificationSampleMain


    Public Sub Main()

        Try

            ' Connect to the AdventureWorks2008R2 database in the default instance
            ' on this server, using integrated security.  If you change this
            ' connection string, be sure to change the service string below.

            Using connection As SqlConnection = _
                new SqlConnection("database=AdventureWorks2008R2;server=.;" + _
                                  "Integrated Security=SSPI")

                connection.Open()

                ' Define the service to receive the notifications. Update this
                ' information if you change the connection string.

                Dim service As String = _
                    "WebCacheNotifications"

                Dim query As String = _
                        "SELECT prod.Name, prod.Class, " + _
                        "       prod.ProductNumber " + _
                        "FROM Production.Product as prod " + _
                        "WHERE prod.Color = 'Black' " 

                Dim command As SqlCommand = connection.CreateCommand()

                command.CommandText = query

                command.Notification = _
                    new SqlNotificationRequest(Guid.NewGuid().ToString(), _
                                               service, _
                                               Int32.MaxValue)

               Dim reader As SqlDataReader = command.ExecuteReader()

               ' Normally, an application would process the results here.

               MsgBox("Registered the notification.")
                  
            ' Notice that the connection dispose method also
            ' disposes the commands and readers created from the
            ' connection.

            End Using  ' Using connection

            

        ' For sample purposes, simply display all exceptions and exit.

        Catch e As SqlException
               MsgBox("SqlException: " + e.Message + vbCrLf  _
                                       + e.StackTrace )
        Catch e As Exception
               MsgBox("Exception: " + e.Message + vbCrLf  _
                                       + e.StackTrace )
        End Try

    End Sub ' Main

End Module 'NotificationSampleMain

End Namespace ' Microsoft.Samples.SqlServer

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

SELECT prod.Name, prod.Class, prod.ProductNumber
FROM Products.Product as prod
    WHERE prod.Color = 'Black'

Компонент Service Broker доставляет сообщения уведомлений службе WebCacheNotifications. Так как данная служба использует очередь WebCacheMessages, сообщения уведомлений появляются в этой очереди. Для обработки сообщений уведомлений приложение контролирует очередь WebCacheMessages.