2010-08-10 11 views
3

Nous avons récemment identifié un problème avec l'une de nos bases de données où suite à une configuration 'fire & forget' (ie: les conversations sont fermées immédiatement après envoi), notre table sys.conversation_endpoints se remplissait de messages DI/DISCONNECTED_INBOUND. Cela a finalement débordé dans le tempDB, l'amenant à se développer énormément et à manger de l'espace disque précieux. Nous avons finalement résolu ce problème en commentant la ligneService Broker: Sys.Conversation_endpoints se remplit de messages CO/CONVERSING lors de l'utilisation de With Withup

END CONVERSATION @handle WITH CLEANUP

dans notre envoi SP et fermer les conversations dans notre SP de réception en utilisant le même code,

END CONVERSATION @handle WITH CLEANUP

Cependant, nous avons maintenant un nouveau problème. Depuis le déplacement des serveurs (et la migration de SQL Server 2005 vers SQL Server 2008), nous avons récemment découvert que sys.conversation_endpoints est maintenant rempli de messages CO/CONVERSING, indiquant que les conversations ne sont pas fermées. Le SP destinataire les ferme, ou au moins exécute la commande pour le faire, donc je ne comprends pas d'où viennent ces messages.

J'ai essayé de revenir à la fin de la conversation au moment de l'envoi, mais cela n'a aucun effet. Est-ce mal de mettre fin aux conversations sur le destinataire en utilisant WITH CLEANUP? Ou y a-t-il un autre problème?

Ce post on techtarget semble suggérer son un bug, et que l'exécution d'un travail pour le nettoyage des restes est la seule solution ...

MISE À JOUR: Pawel a souligné ci-dessous que j'éviterons le feu & Oublier Motif , et j'ai ajouté un SP activé à la file d'attente de l'initiateur pour mettre fin à toutes les conversations. Cependant, sys.conversation_endpoints est encore en train de se remplir, cette fois avec des messages CD/CLOSED. Voici la structure de mes files d'attente

Send_SP:

DECLARE @h UNIQUEIDENTIFIER 
BEGIN DIALOG CONVERSATION @h 
FROM SERVICE 'InitiatorQueue' TO SERVICE 'TargetQueue' 
ON CONTRACT 'MyContract' WITH ENCRYPTION = OFF; 
SEND ON CONVERSATION @h MESSAGE TYPE 'MyMessage' (@msg) 

Receive_SP (Activé SP sur TargetQueue)

DECLARE @type SYSNAME, @h UNIQUEIDENTIFIER, @msg XML; 
DECLARE @target TABLE (
    [message_type_name] SYSNAME, 
    [message_body] VARBINARY(MAX), 
    [conversation_handle] UNIQUEIDENTIFIER 
) 
WHILE(1=1) 
BEGIN TRANSACTION 
    WAITFOR(RECEIVE TOP (1000) 
     [message_type_name],[message_body],[conversation_handle] 
     FROM TargetQueue INTO @target), TIMEOUT 2000    
    IF(@@rowcount!=0) 
    BEGIN 
     WHILE((SELECT count(*) FROM @target) > 0) 
     BEGIN 
     SELECT TOP (1) @type = [message_type_name], 
      @msg = [message_body], 
      @h = [conversation_handle] FROM @target; 
     // Handle Message Here 
     END CONVERSATION @h; 
     DELETE TOP (1) FROM @target; 
    END 
END 
COMMIT TRANSACTION; 

End_SP (Activé SP sur InitiatorQueue)

DECLARE @type SYSNAME, @h UNIQUEIDENTIFIER, @msg XML; 
DECLARE @init TABLE (
    [message_type_name] SYSNAME, 
    [message_body] VARBINARY(MAX), 
    [conversation_handle] UNIQUEIDENTIFIER 
) 
WHILE(1=1) 
BEGIN TRANSACTION 
    WAITFOR(RECEIVE TOP (1000) 
     [message_type_name],[message_body],[conversation_handle] 
     FROM InitiatorQueue INTO @init), TIMEOUT 2000   
    IF(@@rowcount!=0) 
    BEGIN 
     WHILE((SELECT count(*) FROM @init) > 0) 
     BEGIN 
     SELECT TOP (1) @type = [message_type_name], 
      @msg = [message_body], 
      @h = [conversation_handle] FROM @init; 
     END CONVERSATION @h; 
     DELETE TOP (1) FROM @init; 
    END 
END 
COMMIT TRANSACTION; 

Répondre

1

Utilisation du feu -et-oublier le modèle conduira inévitablement à ceci et à d'autres types de problèmes. De plus, toutes les erreurs hypothétiques passeront inaperçues. Y a-t-il une raison pour laquelle vous ne pouvez pas changer le modèle d'échange de messages pour que la cible émette END CONVERSATION (sans nettoyage!) Une fois qu'il reçoit un message et que l'initiateur appelle seulement END CONVERSATION (encore, sans nettoyage) de la cible?

+0

Salut Pawel, je peux certainement supprimer le NETTOYAGE AVEC J'utilise, vous pensez que cela pose problème? Je comprends que le modèle que j'utilise n'est pas le meilleur, mais il convient au type de service que nous avons. – roryok

+0

Lorsque vous dites que le modèle «fire-and-forget» convient au type de service que vous avez, vous reconnaissez implicitement que les problèmes inhérents au fire-and-forget conviennent également au type de service. En d'autres termes, vous êtes en train de dire que vous êtes satisfait des conversations_endpoints, des messages perdus et des erreurs manquées. Personnellement, je ne crois pas que tout type de service (du moins pas que je voudrais utiliser) devrait être OK avec ces choses et c'est pourquoi j'ai recommandé de laisser tomber l'approche fire-and-forget. Mais à la fin du cours, le choix est à vous. –

+0

Salut Pawel, je n'ai pas entièrement compris. Nous avons actuellement un système qui envoie des messages unilatéraux d'une application asp.net à une base de données via une file d'attente de courtier de service. La procédure de réception activée utilise une variable de table et extrait 1000 messages de la file d'attente à la fois, en traitant et en terminant chacun d'eux. Pour cette raison, les messages peuvent rester dans la file d'attente pendant quelques secondes. J'ai supposé (peut-être incorrectement) que changer l'initiateur pour écouter aussi les conversations finales de ces messages mettrait un retard sérieux sur le système (c'est-à-dire quelques secondes par requête), n'est-ce pas? – roryok