2013-08-29 1 views
0

작업자 프로세스가 순서대로 처리 할 수 ​​있도록 일부 메시지를 그룹화해야하는 경우가 있습니다.SSB를 사용하여 대화에서 하나 이상의 메시지를주고 받으십시오.

하지만 내가 발견 한 모든 예는 대화 당 하나의 메시지 만 수행하는 방법을 보여줍니다.

내가 찾고있는 것은 대화에서 하나 이상의 메시지를 보내는 예제와이를 처리하는 방법을 보여주는 예입니다. (나는 둘 모두를 보낼 수도 있지만, 하나만 꺼낼 수있는 것 같습니다.)

답변

1

대화는 메시지가 순서대로 처리되는 경계를 제공하므로 그룹의 모든 메시지를 보내야합니다 동일한 대화 ID로 이 방법은 메시지가 전송 될 때마다 적절한 conversationid를 검색하여 보낼 때마다 ConversationId를 저장할 유틸리티 테이블을 만드는 방법입니다. 당신은 무슨 일이 일어나고 있는지 이해하려면이 읽어해야하지만, 기본적으로 한 번 메시지 처리 절차는 메시지를 보았다 -

SELECT @conversationHandle = ConversationHandle FROM Qproc.SessionConversation 
WHERE 
FromService = @fromService 
AND ToService = @toService 
AND OnContract = @onContract 
AND Terminated IS NULL 

IF @conversationHandle IS NULL 
BEGIN 
    BEGIN DIALOG CONVERSATION @conversationHandle 
     FROM SERVICE @fromService 
     TO SERVICE @toService 
     ON CONTRACT @onContract 
     WITH ENCRYPTION = OFF; --, LIFETIME = 60*60*24*100; 

    -- Store the ongoing conversation for further use 
    INSERT INTO QProc.SessionConversation (FromService, ToService, OnContract,ConversationHandle) 
    VALUES( @fromService, @toService, @onContract, @conversationHandle) 
END 


    -- Create the dialog timer, timeout is seconds; this will notify the ClientQueue if nothing has happened on the conversation 
    --in the timeout period 
    BEGIN CONVERSATION TIMER (@conversationHandle) TIMEOUT = 60*8; 
    SEND ON CONVERSATION @conversationHandle 
    MESSAGE TYPE [http://COMPANYNAME/AsyncTriggerRequestMesssage] 
     (@messageBody); 

만 다른 쪽 끝에서 하나의 메시지를 볼 수있는 이유는 대화 그룹 잠금 함께 할 것입니다 메시지 대기열에 대한보기는 단일 대화로 제한됩니다. 동일한 대화 ID를 다시 사용하면 문제가되지 않습니다. 다음은 그 예받을 수있다 : 그들은 더 이상 사용하고 나면

DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER; 
DECLARE @RecvReqMsg VARCHAR(8000); 
DECLARE @RecvReqMsgName sysname; 


WHILE (1=1) 
    BEGIN 
     BEGIN TRANSACTION; 

     WAITFOR 
     (RECEIVE TOP(1) 
      @RecvReqDlgHandle = conversation_handle, 
      @RecvReqMsg = message_body, 
      @RecvReqMsgName = message_type_name 
      FROM QProc.AsyncTaskServiceQueue 
     ), TIMEOUT 500; 

     IF @@ROWCOUNT=0 
     BEGIN 
      ROLLBACK TRANSACTION; 
      BREAK 
     END 


     IF @RecvReqMsgName = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' 
      BEGIN 
      END CONVERSATION @RecvReqDlgHandle; 
      END 

     IF @RecvReqMsgName='http://COMPANYNAME/AsyncTriggerRequestMesssage' 
      BEGIN 
       DECLARE @BodyDoc XML; 
       SET @BodyDoc=CONVERT(XML, @RecvReqMsg) ; 
       EXEC QProc.AsyncTaskRunTask @BodyDoc; 

      END 

     COMMIT TRANSACTION; 

    END 

마지막으로, 당신이 그 대화를 청소 할 필요가 없습니다 것입니다, 뭔가를 같이 :

DECLARE @conversationHandle UNIQUEIDENTIFIER; 
DECLARE @messageTypeName SYSNAME; 

BEGIN TRANSACTION; 

RECEIVE TOP(1) 
    @conversationHandle = conversation_handle, 
    @messageTypeName = message_type_name 
FROM QProc.AsyncTaskClientQueue; 

IF @conversationHandle IS NOT NULL 
BEGIN 
    --If the DialogTimer message arrives, then there has been no activity on this conversation for a while (see timeout setting in [QProc].[DispatchAsyncTaskMessage]) 
    --so we terminate gracefully and go home. 


    IF @messageTypeName = 'http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer' 
    OR @messageTypeName = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' 
    BEGIN 
     END CONVERSATION @conversationHandle; 
     UPDATE Qproc.SessionConversation SET TERMINATED = getUtcDate() WHERE ConversationHandle = @conversationHandle; 

    END 
    END 

COMMIT TRANSACTION; 
관련 문제