Vue d'ensemble d'une application Service Broker
Les principales étapes de la réception et du traitement des messages sont identiques pour la plupart des applications Service Broker :
L'application entame une transaction.
Si l'application gère l'état, elle obtient un identificateur de groupe de conversations. L'application utilise cet identificateur pour restaurer l'état à partir d'une table d'état. S'il n'existe aucun groupe de conversations comportant des messages prêts à être reçus, l'application restaure la transaction et se ferme.
L'application reçoit un ou plusieurs messages de la file d'attente. Si l'application possède un identificateur de groupe de conversations, elle utilise cet identificateur pour recevoir les messages de ce groupe de conversations. Une fois que tous les messages ont été reçus, l'application valide la transaction et revient à l'étape 1.
L'application valide le contenu des messages en fonction du nom du type de message.
L'application traite les messages en fonction du nom du type de message et du contenu du message.
L'application envoie tous les messages qui ont été traités.
Si l'application gère l'état, elle met à jour la table d'état en utilisant l'identificateur de groupe de conversations comme clé primaire pour la table.
L'application revient à l'étape 3 pour vérifier si d'autres messages sont disponibles.
La structure précise de l'application varie selon les spécifications et le style de communication de l'application, selon que l'application est un service cible ou un service initiateur et selon que Service Broker active l'application ou non.
Par exemple, une application à l'origine d'une conversation envoie un message avant d'entamer la boucle de traitement décrite dans les étapes précédentes. Le service qui a engagé la conversation peut envoyer un message à partir d'un autre programme ou d'une autre procédure stockée, puis utiliser une procédure stockée d'activation pour sa file d'attente. Par exemple, une application de saisie de commandes peut inclure une application externe qui entame la conversation pour saisir la commande. Une fois la commande saisie, il n'est pas nécessaire que l'application externe continue de s'exécuter. Une procédure stockée d'activation du service à l'origine de la conversation envoie la confirmation de la commande lorsqu'une réponse est reçue du service de commande. La procédure stockée d'activation traite également les messages d'erreur Service Broker renvoyés par le service cible, et elle envoie les notifications indiquant que la commande n'a pas pu être confirmée.
Il existe également une autre procédure : au lieu d'envoyer un message à partir d'un programme différent, l'application à l'origine de la conversation peut envoyer un message puis entamer la boucle de traitement dans le cadre du même programme. Indépendamment de ces variantes, les étapes de base restent les mêmes.
Une application qui traite un grand nombre de messages dans le même groupe de conversations peut comptabiliser les messages reçus et valider une transaction après avoir traité un certain nombre de messages. Grâce à cette stratégie de comptabilisation-validation, les transactions sont relativement courtes et l'application peut traiter plusieurs groupes de conversations.
Exemple
L'exemple Transact-SQL suivant traite tous les messages de la file d'attente MyServiceQueue. Le traitement du message est minime. Si le message est un message EndDialog ou Error, le code met fin à la conversation. Pour tous les autres messages, le code crée une représentation XML du message et produit un jeu de résultats qui contient le descripteur de conversation, le nom du type de message et le contenu au format XML. Si 500 millisecondes s'écoulent sans qu'un message soit disponible, le code s'interrompt.
À des fins de simplicité, le script produit un jeu de résultats pour chaque message. Si une erreur se produit pendant la lecture de la file d'attente, le script valide les modifications sans produire de résultat. Par conséquent, ce script supprime silencieusement tous les messages qui provoquent une erreur.
Notes
Dans la mesure où le script affiche simplement des messages, aucun message incohérent n'est possible pour ce script. Le script ne contient donc pas de code permettant de gérer les messages incohérents. La gestion des messages incohérents doit être prise en compte pour l'écriture d'une application de production. Pour plus d'informations sur les messages incohérents, consultez Gestion des messages incohérents.
USE AdventureWorks2008R2 ;
GO
-- Process all conversation groups.
WHILE (1 = 1)
BEGIN
DECLARE @conversation_handle UNIQUEIDENTIFIER,
@conversation_group_id UNIQUEIDENTIFIER,
@message_body XML,
@message_type_name NVARCHAR(128);
-- Begin a transaction, one per conversation group.
BEGIN TRANSACTION ;
-- Get next conversation group.
WAITFOR(
GET CONVERSATION GROUP @conversation_group_id FROM MyServiceQueue),
TIMEOUT 500 ;
-- Restore the state for this conversation group here
-- If there are no more conversation groups, break.
IF @conversation_group_id IS NULL
BEGIN
ROLLBACK TRANSACTION ;
BREAK ;
END ;
-- Process all messages in the conversation group.
WHILE 1 = 1
BEGIN
-- Get the next message.
RECEIVE
TOP(1)
@conversation_handle = conversation_handle,
@message_type_name = message_type_name,
@message_body =
CASE
WHEN validation = 'X' THEN CAST(message_body AS XML)
ELSE CAST(N'<none/>' AS XML)
END
FROM MyServiceQueue
WHERE conversation_group_id = @conversation_group_id;
-- If there is no message, or there is an error
-- reading from the queue, break.
IF @@ROWCOUNT = 0 OR @@ERROR <> 0
BREAK;
-- Process the message. In this case, the program ends the conversation
-- for Error and EndDialog messages. For all other messages, the program
-- produces a result set with information about the message.
SELECT @conversation_handle,
@message_type_name,
@message_body ;
-- If the message is an end dialog message or an error,
-- end the conversation. Notice that other conversations
-- in the same conversation group may still have messages
-- to process. Therefore, the program does not break after
-- ending the conversation.
IF @message_type_name =
'https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
OR @message_type_name =
'https://schemas.microsoft.com/SQL/ServiceBroker/Error'
BEGIN
END CONVERSATION @conversation_handle ;
END ;
END ; -- Process all messages in conversation group.
COMMIT TRANSACTION ;
END ; -- Process all conversation groups.
Voir aussi