Передавать в сообщении никакой ценной информации нам
не надо, так как принимающая сторона должна просто узнать, о том, что таблица
поменялась, а признаком этого служит сам факт доставки сообщения. Более того, в
данной ситуации нет необходимости даже вызывать команду SEND, так как закрытие
диалога (END CONVERSATION) вызывает посылку специального сообщения об этом
печальном событии на принимающую сторону. Однако в реальной ситуации может
понадобиться передать некоторую информацию, и если ее необходимо
структурировать, то придется воспользоваться XML.
Теперь займемся принимающей стороной. Для начала
создадим процедуру пересчета агрегата:
CREATE PROCEDURE AggRecalculate AS
-- очистка очереди
--
RECEIVE * FROM [TargetQueue]
-- небольшая задержка для имитации
действительно долгого расчета
--
WAITFOR DELAY '00:00:02'
UPDATE Big_Aggregate
SET Agg = (SELECT SUM(Data)
FROM Very_Big_Table),
[Time] = GetDate()
GO
|
Процедура готова, но есть одна проблема. Как выполнить
эту процедуру при появлении сообщения в очереди? Конечно, можно, как и раньше, обернуть RECEIVE в WAITFOR, но в этом случае кто-то должен запусить процедуру, чтобы она начала ждать сообщений из очереди. И мало того, сообщение-то у нас
может быть не одно. Значит, нужно чтобы после получения кто-то активизировал
процедуру снова. Другими словами, нужен некий монитор, который следил бы за
состоянием очереди и при появлении в ней сообщений вызывал нашу процедуру. К
счастью, все уже сделано за нас. Такой монитор имеется в Service Broker, и для
его включения достаточно немного изменить параметры очереди, указав, какую
процедуру надо вызвать при получении сообщения: