Introdução ao Service Broker – Processos assíncronos
Depois de termos visto alguns aspectos básicos da estrutura do Service Broker (Monólogos e Diálogos), vamos entender como utilizar o Service Broker para executar processos de forma assíncrona.
A forma mais simples de executar processos de forma assíncrona no Service Broker é utilizar o evento de ativação da fila de mensagens, que seria algo próximo ao que já entendemos como triggers/gatilhos/eventos para novas mensagens inseridas na fila, só que este evento é executado em paralelo ao escopo do qual as mensagens são enviadas.
Para um exemplo simples, criamos o cenário de um monólogo:
USE [master]; CREATE DATABASE DB01; GO ALTER DATABASE DB01 SET ENABLE_BROKER; GO USE DB01; CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'su93rS3nh4'; GO USE DB01; CREATE MESSAGE TYPE Texto VALIDATION = NONE; CREATE CONTRACT Contrato ( Texto SENT BY INITIATOR ); CREATE QUEUE Fila WITH STATUS = ON; CREATE SERVICE Servico ON QUEUE Fila(Contrato); GO
E uma procedure que será executada de forma assíncrona como gatilho de nova mensagem na fila do Service Broker, esta simplesmente fará a leitura das mensagens na fila e inserirá informações sobre estas mensagens em uma tabela:
CREATE TABLE Resultados (Id UNIQUEIDENTIFIER, Texto VARCHAR(30)); GO CREATE PROC USP_Ativacao AS BEGIN DECLARE @Mensagem VARCHAR(30) , @MensagemId UNIQUEIDENTIFIER , @MensagemTipo NVARCHAR(256); WAITFOR ( RECEIVE TOP(1) @Mensagem = [message_body], @MensagemId = [conversation_handle], @MensagemTipo = [message_type_name] FROM Fila ), TIMEOUT 2000 -- 2000ms ou 2s IF @MensagemId IS NOT NULL AND @MensagemTipo = 'Texto' BEGIN WAITFOR DELAY '00:00:01'; INSERT INTO Resultados SELECT @MensagemId, 'Ativação: ' + @Mensagem; END CONVERSATION @MensagemId; END; END; GO
Associamos a execução da procedure ao evento de ativação da fila:
ALTER QUEUE Fila WITH ACTIVATION ( STATUS = ON, PROCEDURE_NAME = USP_Ativacao, MAX_QUEUE_READERS = 1, EXECUTE AS OWNER ) GO
E para demonstração desta estrutura, iniciaremos o monólogo seguido da verificação dos registros de nossa tabela, neste momento ela estará vazia, e após um pequeno delay uma nova verificação da tabela, agora com os registros inseridos de forma assíncrona pela procedure da ativação da fila:
DECLARE @Mensagem VARCHAR(30) , @MensagemId UNIQUEIDENTIFIER; SET @Mensagem = 'Mensagem'; BEGIN DIALOG CONVERSATION @MensagemId FROM SERVICE Servico TO SERVICE 'Servico' ON CONTRACT Contrato; SEND ON CONVERSATION @MensagemId MESSAGE TYPE Texto (@Mensagem); -- Primeira verificação: Vazia SELECT * FROM Resultados; WAITFOR DELAY '00:00:05'; -- Segunda verificação: Dados inseridos SELECT * FROM Resultados; GO
Por fim, podemos desativar a fila e sua ativação, e excluir o banco de dados utilizado para a demonstração:
ALTER QUEUE Fila WITH STATUS = OFF, ACTIVATION ( STATUS = OFF ); GO USE [master]; DROP DATABASE DB01; GO