0

私はSQLブローカーを使用していくつかの非同期タスクを実行しています(私の場合はメールを送信しています)。しかし、私が抱えている問題は、値がキューに挿入されたときに実行されるストアドプロシージャが、XMLメッセージがトリガーからキューに渡されるたびに2回実行されることです。

私はメッセージタイプを持っています:

CREATE MESSAGE TYPE MailMessage
AUTHORIZATION dbo 
VALIDATION = WELL_FORMED_XML

私は契約を結んでいます:

CREATE CONTRACT MailContract
AUTHORIZATION dbo 
(MailMessage SENT BY INITIATOR)

私はキューを持っています:

    CREATE QUEUE dbo.MessageQueue
WITH STATUS=ON, 
 ACTIVATION ( 
 PROCEDURE_NAME = MailExecuter , 
 MAX_QUEUE_READERS = 1,
 EXECUTE AS OWNER );

私には2つのサービスがあります:

    CREATE SERVICE MailSendActivator  
AUTHORIZATION dbo  
ON QUEUE dbo.MessageQueue (MailContract) ; // I have removed this the contract to make it a initiator but it did not worked out  

-- Create target Service   
CREATE SERVICE MailSendExec  
AUTHORIZATION dbo   
ON QUEUE dbo.MessageQueue (MailContract);  

これが私のトリガーです:

 CREATE TRIGGER MailSendTrigOnMailQueue ON dbo.MailQueue
 FOR INSERT 
 As  
 SET NOCOUNT ON;   

DECLARE @MessageBody XML  
DECLARE @TableId int  


SET @MessageBody = (SELECT CreatedDateTime,[Subject], MailType FROM inserted  
FOR XML AUTO)  


If (@MessageBody IS NOT NULL)  
BEGIN  

DECLARE @Handle UNIQUEIDENTIFIER;   
BEGIN DIALOG CONVERSATION @Handle   
FROM SERVICE MailSendActivator   
TO SERVICE 'MailSendExec'   
ON CONTRACT MailContract   
WITH ENCRYPTION = OFF;   

SEND ON CONVERSATION @Handle MESSAGE TYPE MailMessage(@MessageBody);   

END 

ストアドプロシージャがあります。ストアドプロシージャで、ストアドプロシージャが実行されているかどうかをテストテーブルに値を挿入しています。

ストアドプロシージャ:

    CREATE PROCEDURE dbo.MailExecuter  
AS   
BEGIN   

DECLARE @msgBody XML    
DECLARE @dlgId uniqueidentifier 
Insert into TestTable(Name, Test) values('MEX','test'); 
WHILE (1 = 1)   
    BEGIN 

            WAITFOR ( RECEIVE TOP(1) @msgBody = CAST(message_body AS XML),     @dlgId = conversation_handle  FROM dbo.MessageQueue ), TIMEOUT 500    
            IF (@@ROWCOUNT = 0 OR @msgBody IS NULL) 
                BEGIN   
                    BREAK   
                END   
            ELSE   
                BEGIN 


                 DECLARE @Subject nvarchar(200), @CreatedDateTime datetime, @MailType nvarchar(50)


                ---EXEC dbo.SendMails 1,1;

                END  
            END CONVERSATION @dlgId

            END  

    END 

しかし、ストアドプロシージャは2回実行されており、テストテーブルに2回入力されています。send conversation問題はトリガーの部分にあると思います。

私は長い間これに打たれました。どうか、誰かがこれについて私を助けてくれますか

4

1 に答える 1

3

RECEIVE射影リストに を追加する必要がありmessage_type_nameます。受信したメッセージ タイプを確認し、メッセージ タイプが の場合にのみメーリング ルーチンを呼び出す必要がありますMailMessage。現状では、常に 2 番目のメッセージを受け取ります。これはEND DIALOG. その場合、END DIALOG をもう一度呼び出して、送信側のハンドルを閉じる必要があります。

  WAITFOR ( 
      RECEIVE TOP(1) 
         @msgBody = CAST(message_body AS XML),     
         @dlgId = conversation_handle ,
          @msgType = message_type_name
       FROM dbo.MessageQueue ), TIMEOUT 500    
    IF (@@ROWCOUNT = 0 OR @msgBody IS NULL) 
       BREAK   
    ELSE IF @msgType = N'MailMessage'   
    BEGIN 
       DECLARE @Subject nvarchar(200), @CreatedDateTime datetime, @MailType nvarchar(50)
       ---EXEC dbo.SendMails 1,1;
    END  

    END CONVERSATION @dlgId;

車輪を再発明している特定の理由はありますか? これは、sp_send_dbmailすでに機能している方法とほぼ同じです (外部アクティベーションを使用している場合を除く)。

于 2012-10-02T08:21:04.347 に答える