共用方式為


Service Broker 應用程式大綱

大部分的 Service Broker 應用程式會遵循相同的基本步驟來接收和處理訊息:

  1. 應用程式開始交易。

  2. 如果應用程式維持狀態,應用程式會取得交談群組識別碼。應用程式會使用此識別碼從狀態資料表還原狀態。如果交談群組沒有準備接收的訊息,應用程式會回復交易並結束。

  3. 應用程式會從佇列接收一個或多個訊息。如果應用程式具有交談群組識別碼,應用程式會使用交談群組識別碼,來為該交談群組接收訊息。如果沒有任何訊息可供接收,應用程式會認可交易並傳回至步驟 1。

  4. 應用程式會根據訊息類型名稱驗證訊息內容。

  5. 應用程式會根據訊息類型名稱和訊息內容來處理訊息。

  6. 應用程式會傳送因為處理所產生的任何訊息。

  7. 如果應用程式維持狀態,應用程式會更新狀態資料表,使用交談群組識別碼做為資料表的主要索引鍵。

  8. 應用程式會傳回步驟 3,以檢查是否有更多的訊息可使用。

應用程式的精確結構取決於應用程式的需求、應用程式的通訊樣式、應用程式是目標服務或起始服務,Service Broker 是否啟動應用程式。

例如,起始應用程式會在開始上一個步驟所述的處理迴圈之前,先傳送訊息。起始服務可能會從另一個程式或是預存程序傳送訊息,然後為起始服務佇列使用啟用預存程序。例如,訂單輸入應用程式可以包括外部應用程式,以起始交談來輸入訂單。在輸入訂單之後,外部應用程式不需要繼續執行。當回應從訂單服務傳回時,起始服務的啟用預存程序會傳送訂單通訊。啟用預存程序也會處理任何由目標服務傳回的 Service Broker 錯誤訊息,並傳送無法確認的訂單之通知。

或者,起始應用程式與其從不同的程式傳送訊息,還不如傳送訊息,然後啟動處理迴圈做為相同程式的一部分。不論這些變化為何,基本的大綱仍然保持相同。

在相同的交談群組中處理大量訊息的應用程式,可能會保留接收的訊息計數,並在處理某些數目的訊息之後認可交易。這個計數和認可策略允許應用程式保持相當短暫的交易,並讓應用程式處理不同的交談群組。

範例

下列 Transact-SQL 範例會處理佇列 MyServiceQueue 上的所有訊息。會以最簡單的方式處理訊息。如果訊息是 EndDialogError 訊息,程式碼會結束交談。對於任何其他訊息,程式碼會建立訊息的 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.