Share via


Service Broker 응용 프로그램 개요

대부분의 Service Broker 응용 프로그램에서는 다음과 같은 동일한 기본 단계를 따라 메시지를 받고 처리합니다.

  1. 트랜잭션을 시작합니다.

  2. 상태를 관리하는 응용 프로그램의 경우 대화 그룹 식별자를 가져옵니다. 이 식별자는 상태 테이블에서 상태를 복원하는 데 사용됩니다. 받을 준비가 된 메시지가 있는 대화 그룹이 없는 경우 응용 프로그램은 트랜잭션을 롤백하고 종료됩니다.

  3. 큐에서 하나 이상의 메시지를 받습니다. 대화 그룹 식별자를 가져온 응용 프로그램에서는 이 대화 그룹 식별자를 사용하여 해당 대화 그룹의 메시지를 받습니다. 받을 수 있는 메시지가 더 이상 없으면 응용 프로그램은 트랜잭션을 커밋하고 1단계로 돌아갑니다.

  4. 메시지 유형 이름을 기반으로 메시지 내용의 유효성을 검사합니다.

  5. 메시지 유형 이름과 메시지 내용에 따라 메시지를 처리합니다.

  6. 처리 결과 생성된 메시지를 보냅니다.

  7. 상태를 관리하는 응용 프로그램의 경우 대화 그룹 식별자를 상태 테이블의 기본 키로 사용하여 상태 테이블을 업데이트합니다.

  8. 3단계로 돌아가서 사용할 수 있는 다른 메시지가 있는지 확인합니다.

응용 프로그램의 정확한 구조는 응용 프로그램의 요구 사항, 응용 프로그램의 통신 스타일, 응용 프로그램이 대상 서비스인지 시작 서비스인지, Service Broker에서 응용 프로그램을 활성화하는지에 따라 달라집니다.

예를 들어 시작 응용 프로그램에서는 위 단계에 설명된 처리 루프를 시작하기 전에 메시지를 보냅니다. 시작 서비스는 다른 프로그램 또는 저장 프로시저에서 받은 메시지를 보낸 다음 시작 서비스 큐의 활성화 저장 프로시저를 사용할 수 있습니다. 예를 들어 주문 입력 응용 프로그램에는 주문을 입력하기 위한 대화를 시작하는 외부 응용 프로그램이 포함될 수 있습니다. 주문이 입력된 후에는 이 외부 응용 프로그램을 계속 실행할 필요가 없습니다. 시작 서비스의 활성화 저장 프로시저는 주문 서비스에서 응답이 반환될 때 주문 확인 메시지를 보냅니다. 또한 활성화 저장 프로시저는 대상 서비스에서 반환된 Service Broker 오류 메시지를 처리하고 주문을 확인할 수 없다는 알림을 보냅니다.

다른 프로그램에서 메시지를 보내는 대신 시작 응용 프로그램에서 메시지를 보낸 다음 동일한 프로그램의 일부로 처리 루프를 시작할 수도 있습니다. 어떤 방법을 사용하든 기본적인 단계는 동일합니다.

동일한 대화 그룹의 많은 메시지를 처리하는 응용 프로그램에서는 받은 메시지 수를 세고 일정 개수의 메시지를 처리한 후 트랜잭션을 커밋할 수 있습니다. 이 계산 후 커밋 전략을 사용하면 응용 프로그램에서 트랜잭션을 비교적 짧게 유지하고 다른 대화 그룹을 처리할 수 있습니다.

다음 Transact-SQL 예에서는 MyServiceQueue 큐의 모든 메시지를 처리합니다. 이 메시지 처리 작업은 최소한으로 수행됩니다. 메시지가 EndDialog 또는 Error 메시지인 경우 코드에서 대화를 종료합니다. 다른 메시지의 경우 코드에서는 메시지의 XML 표현을 만들고 대화 핸들, 메시지 유형 이름 및 XML이 포함된 결과 집합을 생성합니다. 500밀리초 동안 사용 가능한 메시지가 없으면 코드가 종료됩니다.

간단히 하기 위해 이 스크립트에서는 각 메시지에 대한 결과 집합을 생성합니다. 큐에서 읽는 동안 오류가 발생하면 스크립트에서는 결과를 생성하지 않고 변경 내용을 커밋합니다. 따라서 이 스크립트는 오류가 발생한 메시지를 자동으로 제거합니다.

[!참고]

이 스크립트는 메시지를 표시하기만 하므로 이 스크립트에서 포이즌 메시지는 처리할 수 없습니다. 따라서 이 스크립트에는 포이즌 메시지를 처리하는 코드가 들어 있지 않습니다. 프로덕션 응용 프로그램은 포이즌 메시지를 처리하도록 작성해야 합니다. 포이즌 메시지에 대한 자세한 내용은 포이즌 메시지 처리를 참조하십시오.

USE AdventureWorks2008R2 ;
GO

-- Process all conversation groups.

WHILE (1 = 1)
BEGIN

DECLARE @conversation_handle UNIQUEIDENTIFIER,
        @conversation_group_id UNIQUEIDENTIFIER,
        @message_body XML,
        @message_type_name 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 TRANSACTION ;
    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.