Es útil cuando se necesita procesamiento asíncrono o distribuir trabajos en diferentes computadores
Para habilitarlo es necesario ejecutar la siguiente sentencia T-SQL
ALTER DATABASE AdventureWorks SET ENABLE_BROKER
Para configurar la arquitectura del Service Broker contamos con 4 objectos.
Message Type: Define el nombre del mensaje y el tipo de informacion que el mensaje contiene. Estos mensajes deben ser creados en ambas partes de la conversacion
CREATE MESSAGE TYPE message_type_name
[AUTHORIZATION owner_name]
[VALIDATION =
{NONE EMPTY WELL_FORMED_XML
VALID_XML WITH SCHEMA COLLECTION schema_collection_name}]
Los posibles valores para VALIDATION son:
NONE: no se realiza ninguna validación
EMPTY: El cuerpo del mensaje debe tener valor NULO
WELL_FORMED_XML: Debe contener un XML bien formado
VALID_XML WITH SCHEMA COLLECTION: El contenido del XML debe cumplir con el XML SCHEMA señalado
Para modificarlo necesitamos utiliza la sentecia ALTER
ALTER MESSAGE TYPE message_type_name
VALIDATION =
{NONE EMPTY WELL_FORMED_XML
VALID_XML WITH SCHEMA COLLECTION schema_collection_name}]
Y para eliminar
DROP MESSAGE TYPE message_type_name
Contract: Define los tipos de mensajes que un servicio puede utilizar en una conversación y la dirección en que los mensajes pueden ser enviados
CREATE CONTRACT contract_name
[ AUTHORIZATION owner_name ]
( { message_type_name SENT BY { INITIATOR TARGET ANY }
[ DEFAULT ] } [ ,...n] )
Los posibles valores para SENT BY son:
INITIATOR: indica que solo el iniciador puede enviar dicho tipo de mensaje
TARGET: Indica que solo el destino puede enviar dicho tipo de mensaje
ANY: Indica que tanto el iniciador y el destino pueden enviar dicho tipo de mensaje
Para eliminar un contrato la sintaxis es la siguiente:
DROP CONTRACT contract_name
Queue: Define la ubicación donde se almacenaran los mensajes hasta que un servicio este disponible para atender los mensajes
CREATE QUEUE [database_name.[schema_name].schema_name.] queue_name
[ WITH
[ STATUS = { ON OFF } [ , ] ]
[ RETENTION = { ON OFF } [ , ] ]
[ ACTIVATION (
[ STATUS = { ON OFF } , ]
PROCEDURE_NAME = stored_procedure_name,
MAX_QUEUE_READERS = max_readers ,
EXECUTE AS { SELF 'user_name' OWNER }
) ]
]
[ ON { filegroup [ DEFAULT ] } ]
STATUS: Especifica si la cola esta habilitada. Cuando esta en OFF ningún servicio podría retirar mensajes de la cola.
RETENTION:Indica si la cola debe mantener todos los mensajes hasta que la conversación finalice
ACTIVATION STATUS: Indica si se debe activar el procedimiento almacenado cuando llegue un mensaje a la cola
MAX_QUEUE_READERS: Indica la cantidad máxima de servicio que correrán simultáneamente
EXECUTE AS: especifica la cuenta de usuario con que correrá el servicio
Para modificar esta es la sintaxis
ALTER QUEUE [database_name.[schema_name].schema_name.] queue_name
[ WITH
[ STATUS = { ON OFF } [ , ] ]
[ RETENTION = { ON OFF } [ , ] ]
[ ACTIVATION (
[ STATUS = { ON OFF } , ]
PROCEDURE_NAME = stored_procedure_name,
MAX_QUEUE_READERS = max_readers ,
EXECUTE AS { SELF 'user_name' OWNER }
] DROP })
]
Para eliminar una cola la sintaxis es:
DROP QUEUE [database_name.[schema_name].schema_name.] queue_name
SERVICE: Relaciona las colas con los contractos
CREATE SERVICE service_name
[ AUTHORIZATION owner_name ]
ON QUEUE [ schema_name. ]queue_name
[ ( contract_name [DEFAULT] [ ,...n ] ) ]
Para modificar el servicio utilice la siguiente sintaxis:
ALTER SERVICE service_name
[ON QUEUE [schema_name].queue_name]
[(ADD CONTRACT contract_nameDROP CONTRACT contract_name)]
ON QUEUE: Especifica la nueva cola para el servicio y mueve todos los mensajes de la cola vieja a la nueva
ADD CONTRACT: Añade un contrato a la colección de contratos asociados a este servicio
DROP CONTRACT: Especifica los contratos que se eliminaran del servicio. En caso de que alguno se este ejecutando mostrara un mensaje de error.
Para comenzar a usar los servicios se deben establecer una conversación. Estos son los pasos para establecer una conversación.
Crear la variable que identificara de manera única la conversación.
DECLARE @dialog_handle uniqueidentifier
Iniciar la conversación
BEGIN DIALOG [ CONVERSATION ] @dialog_handle
FROM SERVICE initiator_service_name
TO SERVICE 'target_service_name'
[ , { 'service_broker_guid' 'CURRENT DATABASE' } ]
[ ON CONTRACT contract_name ]
[ WITH
[ { RELATED_CONVERSATION = related_conversation_handle
RELATED_CONVERSATION_GROUP = related_conversation_group_id } ]
[ [ , ] LIFETIME = dialog_lifetime ]
[ [ , ] ENCRYPTION = { ON OFF } ] ]
RELATED_CONVERSATION o RELATED_CONVERSATION_GROUP relaciona un nuevo dialogo con una conversacion existente
LIFETIME= tiempo en segundo en la que será valido el dialogo
Enviar mensaje
SEND
ON CONVERSATION conversation_handle
[ MESSAGE TYPE message_type_name ]
[ ( message_body_expression ) ]
El destino recibe el mensaje
[ WAITFOR ( ]
RECEIVE [ TOP ( n ) ]
FROM
[ INTO table_variable ]
[ WHERE { conversation_handle = conversation_handle
conversation_group_id = conversation_group_id } ]
[ ) ] [ , TIMEOUT timeout ]
WAITFOR: especifica que la clausula RECEIVE espera un mensaje
RECEIVE: lee los mensajes de la cola y los elimina en caso de que la opción RETENTION de la cola este desactivada.
TOP: Indica cuantos mensajes se van a leer de la cola, sino se especifica se leerán todos los mensajes
INTO: Ingresa todos los mensajes en una tabla para ser tratados después
WHERE: especifica la conversación o grupo de conversaciones para los mensajes leídos
TIMEOUT: Especifica el tiempo en milisegundos en que la instrucción espera un mensaje.
Para terminar la conversación
END CONVERSATION conversation_handle
[ [ WITH ERROR = failure_code DESCRIPTION = 'failure_text' ]
[ WITH CLEANUP ]
Ejemplo de todo el proceso
CREATE MESSAGE TYPE TicketRequest AUTHORIZATION dbo
VALIDATION = WELL_FORMED_XML
CREATE MESSAGE TYPE TicketStatus AUTHORIZATION dbo
VALIDATION = WELL_FORMED_XML
CREATE QUEUE SenderQUEUE
CREATE QUEUE ReceiverQUEUE
CREATE CONTRACT Ticketservicescontract
(TicketRequest SENT BY INITIATOR,
TicketStatus SENT BY TARGET)
CREATE SERVICE SendTicketingService ON
Queue SenderQUEUE
(Ticketservicescontract)
CREATE SERVICE ReceiveTicketingService ON
Queue ReceiverQUEUE
(Ticketservicescontract)
declare @message xml
declare @conversationhandle UNIQUEIDENTIFIER
set @message =
'
BEGIN DIALOG CONVERSATION @conversationHandle
FROM SERVICE SendTicketingService
TO SERVICE 'ReceiveTicketingService'
ON CONTRACT Ticketservicescontract
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION @conversationHandle
MESSAGE TYPE TicketRequest
(@message);
END CONVERSATION @conversationHandle
CREATE PROCEDURE STP_ProcessQueue
AS
BEGIN
DECLARE @conversation_handle UNIQUEIDENTIFIER,
@message_body XML,
@message_type_name NVARCHAR(128);
RECEIVE TOP(1)
@conversation_handle = conversation_handle,
@message_type_name = message_type_name,
@message_body = message_body
FROM [dbo].[ReceiverQUEUE]
-- DO SOMETHING with the message
if @message_type_name = 'TicketRequest'
BEGIN
-- EXEC stp_processticketrequest @message_body
SELECT @message_body
END
END CONVERSATION @conversation_handle ;
END
GO
ALTER QUEUE ReceiverQUEUE
WITH ACTIVATION (STATUS = ON,
PROCEDURE_NAME = STP_ProcessQUEUE,
EXECUTE AS OWNER)
GO
EXEC STP_ProcessQUEUE
No hay comentarios:
Publicar un comentario