Plan de l’application Service Broker

S’applique à :SQL ServerAzure SQL Managed Instance

Les principales étapes de la réception et du traitement des messages sont identiques pour la plupart des applications Service Broker :

  1. L'application entame une transaction.

  2. 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 avec des messages prêts à être reçus, l’application annule la transaction et ferme.

  3. 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.

  4. L'application valide le contenu des messages en fonction du nom du type de message.

  5. L'application traite les messages en fonction du nom du type de message et du contenu du message.

  6. L'application envoie tous les messages qui ont été traités.

  7. 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.

  8. 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 de lancement peut envoyer un message à partir d’un autre programme ou procédure stockée, puis utiliser une procédure stockée d’activation pour la file d’attente du service de lancement. Par exemple, une application d’entrée de commande peut inclure une application externe qui déclenche 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 retournés par le service cible et envoie des notifications que la commande n’a pas pu être confirmée.

Sinon, au lieu d’envoyer un message à partir d’un autre programme, l’application de lancement peut envoyer un message, puis démarrer 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 conserver le nombre de messages reçus et valider une transaction après un traitement d’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.

Examples

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. Par conséquent, le script ne contient pas de code pour gérer les messages empoisonnés. 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 empoisonnés, consultez Gérer les messages empoisonnés.

Notes

Les exemples de code de cet article ont été testés à l’aide de l’exemple de base de données AdventureWorks2025, que vous pouvez télécharger à partir de la Microsoft SQL Server Samples and Community Projects page d’accueil.

USE [AdventureWorks2022];
GO

-- Process all conversation groups.
WHILE (1 = 1)
    BEGIN
        DECLARE @conversation_handle AS UNIQUEIDENTIFIER,
            @conversation_group_id AS UNIQUEIDENTIFIER,
            @message_body AS XML,
            @message_type_name AS 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;
                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.