2010-11-23 24 views
2

Je remarque que certaines conversations ne sont pas fermées et restent en état CONVERSANT. La chose étrange est, la file d'attente est configurée pour traiter seulement 1 message à la fois. En pratique, cependant, il y a deux conversations en état CONVERSANT, une qui fait vraiment du travail, et une autre qui semble être bloquée. Une chose que j'utilise est une seule file d'attente et un seul service, qui diffère des implémentations habituelles du courtier de services (ce qui ressemble plus à un monologue qu'à un dialogue). Je commence la SP d'activation avec:Les conversations du service Broker ne sont pas fermées (rester dans l'état CONVERSANT)

RECEIVE TOP(1) 
    @Handle = conversation_handle, 
    @MsgTypeName = message_type_name 
FROM [//MyQueue] 

IF (@@ROWCOUNT = 0) 
    RETURN 
ELSE IF ((@MsgTypeName is null) or (@Handle is null)) 
    RETURN 
ELSE IF (@MsgTypeName != '//MyRequest') 
    BEGIN 
     END CONVERSATION @Handle 
     RETURN 
    END 
+0

Il sera difficile de vous aider si vous ne fournissez pas plus de code (je ne parle pas de la logique métier, mais des parties liées au courtier) ainsi que des commandes DDL que vous avez utilisées pour tout configurer. –

Répondre

0

en utilisant "END CONVERSATION 'poignée de conversation' AVEC CLEANUP;" n'est pas un moyen efficace de mettre fin à la conversation.

Le courtier de services est conçu pour les boîtes de dialogue et non pour les conversations monologues. Cela devrait être aussi la raison pour laquelle il y a 2 conversations (pour envoyer le service et autre pour recevoir le service - puisque les services peuvent résider dans différentes bases de données/instances)

Vous pouvez créer un service d'envoi, qui est utilisé pour envoyer des messages et recevoir "Terminer la boîte de dialogue" messages et termine la boîte de dialogue, l'autre sorcière reçoit des messages et fait un peu de traitement avec eux + termine la boîte de dialogue lorsque le travail est terminé.

-1
ELSE IF (@MsgTypeName != '//MyRequest') 
    BEGIN 
     END CONVERSATION @Handle 
     RETURN 
    END 

Pas une bonne idée. Essayez ceci:

IF @MsgTypeName = '//MyRequest' 
BEGIN 
    /* Do something here with the message */ 
END 
ESLE IF @MsgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' 
BEGIN 
    END CONVERSATION @Handle 
END 
ELSE IF @MsgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error' 
BEGIN 
    END CONVERSATION @Handle 
    /* do some error reporting here */ 
END 

Rappelons que les deux et la cible Initiateur doivent mettre fin à la conversation avant de pouvoir être vraiment terminé. Et que la cible est celle qui envoie généralement le premier message CONVERSATION FIN à l'initiateur. Alors maintenant, l'initiateur (dans le code ci-dessus) doit inspecter le type de message entrant et agir en conséquence. Si cela est enveloppé dans un proc stocké, il recevra à la fois le message de réponse réel et le message END CONVERSATION, l'un après l'autre.