Образовательный портал Claw.ru
Всё для учебы, работы и отдыха
» Шпаргалки, рефераты, курсовые
» Сочинения и изложения
» Конспекты и лекции
» Энциклопедии

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

Как все это работает

Сначала, как уже было вкратце описано, сервер получает стандартный пакет с текстом запроса и небольшим довеском. Этот довесок содержит имя сервиса ServiceBroker-а (который будет использоваться для доставки), строку, являющуюся идентификатором извещения и величину таймаута извещения. Всех этих параметров в примере нет, они задаются неявно, при создании экземпляров класса SqlDependency. Текст запроса может содержать несколько T-SQL-запросов. Запросы могут также находиться внутри процедуры или функции. Изменения в результатах всех этих запросов будут отслеживаться. Механизм отслеживания изменений, как это ни странно, совсем не нов, он присутствует в SQL Server с прошлой версии и используется для индексированных представлений. Точно так же, как индексированное представление узнает об изменениях данных в таблицах, из которых она состоит, механизм извещения узнает о том, что изменились данные результата запроса. Механизм хороший и проверенный, но, к сожалению, обладающий рядом довольно серьезных ограничений. Практически все ограничения, накладываемые на индексированные представления, справедливы и для механизма извещений. Обратите внимание, что в примере имя таблицы в запросе включает еще и имя схемы, а имена полей перечислены явно, иначе пример не заработал бы.

ПРИМЕЧАНИЕ

Полный список ограничений можно найти здесь: http://msdn2.microsoft.com/library/aewzkxxh(en-us,vs.80).aspx

После того, как сервер определит, что произошли изменения, затрагивающие данные в результате запроса, в отличие от механизма индексированных представлений, копия измененных данных не создается. Вместо этого формируется сообщение для ServiceBroker-а, который использует для доставки этого сообщения адресату специально для этого созданный контракт [http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification] и сервис [http://schemas.microsoft.com/SQL/Notifications/QueryNotificationService]. Адресатом является хранимая процедура sp_DispatcherProc, которая смотрит, кто именно на это сообщение подписан, и рассылает подписчикам извещения об изменении данных.

ПРИМЕЧАНИЕ

Поскольку процедура sp_DispatcherProc реализована на .Net, то для того, чтобы данный способ извещения работал, на сервере должно быть разрешено выполнение .Net-процедур.

Вся прелесть заключается в том, что клиенту нет никакой необходимости держать постоянное соединение с сервером (что хорошо видно на примере). Это извещение доставляется подписчику отдельно от подключения к базе, по HTTP или TCP/IP. В принципе протокол можно задать явно, но по умолчанию, если клиентская ОС поддерживает HTTP (как Windows 2003 или Windows XP SP2), то используется HTTP, в противном случае – TCP. Естественно, для того чтобы это работало, клиент должен быть доступен серверу по сети, что надо учитывать при развертывании подобных систем. Для более тонкой настройки при инициализации SqlDependency можно указать параметры соединения, как уже упоминалось, протокол, а также тип аутентификации (на данный момент none или Integrated) и таймаут подписки. Сейчас эти настройки передаются в конструкторе, впоследствии будут сделаны соответствующие свойства, и количество настроек, возможно, будет увеличено.

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

Сообщение об изменениях приходит только один раз, вне зависимости от того, сколько строк было изменено, удалено или добавлено. Сообщение также не содержит никакой информации об измененных строках и их количестве. Единственное, что известно об изменениях – в свойстве Info объекта SqlNotificationEventArgs содержится информация о том, какие именно действия привели к посылке сообщения об изменении данных. При посылке извещения сервер предпочитает подстраховаться и послать сообщение лишний раз, чем не послать его вообще. Сообщение будет послано не только в случае реального изменения данных, но и если одна из таблиц, участвующих в запросе, была удалена, изменена или обрезана, и даже в том случае, когда выполнение DML-оператора над запрошенным набором не привело к реальному изменению данных, например: UPDATE tbl SET a = a WHERE b = @XСтоит сказать пару слов об обработке ошибок. Дело в том, что если на сервер будет послан корректный с точки зрения T-SQL запрос, отследить изменения для которого по каким-либо причинам невозможно (например, запрос не удовлетворяет строгим ограничениям внутреннего механизма извещения), то исключение сгенерировано не будет, а просто немедленно будет вызван обработчик изменения данных с признаком Invalid Query. Поэтому в реальных приложениях обработчик обязательно должен учитывать подобный вариант развития событий.

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

Клиент 1:

...

SqlCommand cmd = new SqlCommand(

 "select id, [tm], Data from dbo.AsyncTest where id = @id")

cmd.Parameters.AddWithValue("@id", 2);

...

Клиент 2:

...

SqlCommand cmd = new SqlCommand(

 "select id, [tm], Data from dbo.AsyncTest where id = @id")

cmd.Parameters.AddWithValue("@id", 3);

...

На эти два запроса ядром сервера будет сформирован один запрос на отслеживание изменений, но первый клиент получит извещение только в том случае, если поменялась запись с ID = 2, а второй – если поменялась запись с ID = 3


Рекомендуем скачать другие рефераты по теме: рефераты на казахском языке, реферат на тему время.


Категории:




Предыдущая страница реферата | 10  11  12  13  14  15  16  17  18  19  20 |


Поделитесь этой записью или добавьте в закладки

   



Рефераты от А до Я


Полезные заметки

  •