共用方式為


移除有害訊息

「有害訊息」是包含應用程式無法成功處理之資訊的訊息。例如,製造工作站可能會在變更訂單棄用存貨的零件之前,提交要求以撤回零件。變更訂單會在存貨要求處於傳輸中時生效。存貨管理應用程式會從工作站接收要求,但無法成功地處理要求,且更新庫存中零件數目的資料庫要求會失敗。然後,包含接收作業的交易會回復,並讓訊息返回佇列。在此情況下,應用程式會繼續接收相同訊息,更新繼續失敗,訊息則返回佇列。

有害訊息不是損毀的訊息,也可能不是無效要求。Service Broker 包含偵測損毀之訊息的訊息完整性檢查。應用程式通常也會驗證訊息的內容,並捨棄包含不合法要求的訊息。相反,許多有害訊息在建立訊息時是有效的,但隨後卻變成無法處理。

有害訊息自動偵測

Service Broker 提供有害訊息的自動偵測。包含 RECEIVE 陳述式的交易回復五次後,Service Broker 會藉由自動將佇列狀態設定為 OFF,停用交易從中接收訊息的所有佇列。此外,Service Broker 會產生 Broker:Queue Disabled 類型的事件。

管理員可以使用 SQL Server Agent 警示,在停用佇列時收到通知。開發人員還可以建立應用程式,偵測 Service Broker 何時停用佇列。該應用程式通常會檢查佇列中的訊息,以尋找有害訊息。一旦應用程式確定無法處理的訊息,該應用程式便會將佇列狀態設定為 ON,並結束訊息的交談,且傳回錯誤。偵測有害訊息的應用程式必須在結束交談時小心清除與交談相關的任何狀態。如需有關建立應用程式以從有害訊息復原的詳細資訊,請參閱<處理有害訊息>。

由管理員移除有害訊息

大多數應用程式都應以程式設計方式追蹤和移除有害訊息。然而,有時需要手動移除有害訊息。例如,應用程式執行復原的部份可能無法偵測有害訊息,或無法安全地清除交談的已儲存狀態。

手動移除訊息會面臨中斷重要交談的風險。因此,在從佇列移除訊息之前,請始終檢查有害訊息。若要查看訊息的內容,請開始交易、接收訊息主體、顯示訊息主體,然後回復交易。在您確信有問題的訊息為有害訊息之前,請務必回復交易。

範例

下列範例顯示如何安全地檢查訊息,以讓交談控制代碼 ExpenseQueue 佇列中的 e29059bb-9922-40f4-a575-66b2e4c70cf9。

use AdventureWorks2008R2 ;
GO

-- Sample to show the content of a message, then return
-- the message to the queue. This may be useful to determine
-- whether a specific message cannot be processed due to the
-- content of the message.

-- Every exit path from the transaction rolls back the transaction.
-- This code is intended to inspect the message, not remove the
-- message from the queue permanently. The transaction must roll
-- back to return the message to the queue.

BEGIN TRANSACTION ;

  -- To print the body, the code needs the message_body and
  -- the encoding_format.

  DECLARE @messageBody VARBINARY(MAX),
          @validation NCHAR ;

  -- Receive the message. The WAITFOR handles the case where
  -- an application is attempting to process the message when
  -- this batch is submitted. Replace the name of the queue and
  -- the conversation_handle value.

  WAITFOR(
    RECEIVE TOP(1) 
            @messageBody = message_body,
            @validation = validation
      FROM dbo.ExpenseQueue
      WHERE conversation_handle =
           'e29059bb-9922-40f4-a575-66b2e4c70cf9'
  ), TIMEOUT 2000 ;

  -- Roll back and exit if the message is not available
  -- in two seconds.

  IF @@ROWCOUNT = 0
    BEGIN
      ROLLBACK TRANSACTION ;
      PRINT 'No message available.' ;
      RETURN ;
    END

  -- Print the message based on the encoding format of
  -- the message body.

  IF (@validation = 'E')
    BEGIN
      PRINT 'Empty message.' ;
    END ;
  ELSE IF (@validation = 'X')
    BEGIN
      PRINT CONVERT(nvarchar(MAX), @messageBody) ;
    END ;
  ELSE IF (@validation = 'N')
    BEGIN
      PRINT 'No validation -- binary message:'
      PRINT @messageBody ;
    END

ROLLBACK TRANSACTION
GO

當您找到有害訊息時,請結束交談。下列範例會結束交談 e29059bb-9922-40f4-a575-66b2e4c70cf9。

-- End the conversation. Do this only if the message cannot be
-- processed by the normal procedure.

END CONVERSATION 'e29059bb-9922-40f4-a575-66b2e4c70cf9'
    WITH ERROR = 127 DESCRIPTION = N'Unable to process message.' ;
GO

交談結束後,Service Broker 會捨棄該交談的訊息。請注意,正常處理訊息的應用程式不會接收此交談的 EndDialogError 訊息。因此,如果應用程式狀態保持不變,您必須在結束交談並傳回錯誤時小心移除與交談關聯的狀態。

如果服務無法處理訊息,這表示服務無法完成交談的工作。結束交談並傳回錯誤會通知交談中的其他參與者工作失敗。