| ||||||||||||||||
| ||||||||||||||||
| ||||||||||||||||
Сервис событий в SQL-сервере Погружение в проблематику Достаточно нередко у разработчиков клиент-серверных приложений возникает необходимость организовать некий механизм, позволяющий по событию на SQL-сервере уведомить того или иного клиента. Ещё чаще это является розово-голубой мечтой заказчика, чтобы разработчик реализовал такой механизм. Например, при превышении лимитов отгрузки какому-либо потребителю, должны быть немедленно уведомлены менеджеры, работающие с этим потребителем. Некоторые заказчики систем требуют (а мечтают об этом все заказчики без исключения), чтобы при изменении каких-то данных, у остальных пользователей системы эта информация автоматически обновлялась, причем незамедлительно. Здесь не будет обсуждаться целесообразность такого требования (оно имеет много оснований для критики), здесь будут обсуждаться только пути решения. Microsoft SQL-сервер имеет штатное средство для организаций уведомлений - alerts, но это средство имеет весьма ограниченное применение, по большому счету не дающее возможность создать на его основе гарантированно работающий механизм. И вот почему: Связь с клиентской программой может быть осуществлена путем посылки e-mail или эмуляцией посылки "net send". И то, и другое неудобно для получения уведомления. Средство e-mail неудобно по причинам:
a) нет гарантии доставки, почта может теряться. Посылка путем "net send" неудобна по следующим причинам:
a) нет гарантии доставки, так как это организовано через средство mailslot, не имеющее такой гарантии. И в целом средство alerts неудобно необходимостью регистрации каждого клиента в качестве оператора и соответствующей настройкой. Т.е. для простейших случаев alerts применить можно. Но для большинства случаев оно неприменимо. Известные реализации и концепции Широкой общественности известны несколько вариантов реализации механизма уведомления сервером клиента. Это:
1. Создание объекта (Extended Stored Procedure или ActiveX), посредством которого SQL-сервер уведомляет
клиента через сокеты TCP/IP. При этом на клиенте организована прослушка, т.е. клиентская программа стала
сервером TCP/IP.
2. Создание объекта (Extended Stored Procedure или ActiveX), посредством которого SQL-сервер уведомляет
клиента через named pipes или mailslots. При этом на клиенте организована прослушка того или другого. 3. Периодический опрос SQL-сервера клиентом (периодическое чтение специальной таблички евентов). Это очень простой путь, но, тем не менее, свободный от большинства вышеперечисленных недостатков. К сожалению, этот метод имеет свои специфичные 2 недостатка: a) получение уведомления может быть задержано на величину таймаута опроса и b) при маленьком таймауте возникает существенный трафик. Тем не менее, при небольшом кол-ве сессий, этот метод вполне пригоден и незаслуженно обойден вниманием. Предлагаемый вариант решения
Вашему вниманию предлагается вариант решения проблемы, свободный от вышеперечисленных (всех
вышеперечисленных!) проблем, но вместе с тем достаточно простой. Идея такова: на сервер помещается
некий двоичный объект, который sql-сервер может вызывать (а это может быть только Extended Stored
Procedure или ActiveX-объект), имеющий два невзаимосвязанных метода. Готовое решение Решение состоит из ActiveX-объекта в виде файла AlgoEvt.dll и двух хранимых процедур spWaitForEvent и spRaiseEvent. Перед использованием этот файл надо поместить на сервер и зарегистрировать ActiveX-объект с помощью системной утилиты regsvr32.exe. Дальше вся работа будет производиться через хранимые процедуры. В готовом решении реализована несколько бОльшая функциональность, чем в описанной концепции. Кроме самого факта события, можно передать также произвольную информацию в виде строки в размере до 250 символов. Каждая процедура имеет два параметра. Первая - это уникальный идентификатор-адрес, о котором говорилось выше, а второй параметр - дополнительная передающаяся информация. spWaitForEvent надо вызвать с клиента из отдельного потока (приоритет потока можно выбрать самый низкий). При получении события, процедуру надо перезапустить. Тайм-аут исполнения запроса надо задать бесконечный. Решение здесь: SQLEventsService.zip Преимущества решения
1. Независимость от сетевого протокола и настроек сети. Был бы коннект к sql-серверу. |
|
| ||||||||||||||||
|