2011-05-12 19 views
0

我有一個工作流服務,有幾個收聽MSMQ隊列。我想要實現以下行爲:可以通過工作流服務更改MSMQ消息錯誤處理的行爲嗎?

  1. 如果發生相關異常(即 - 工作流實例消失),請丟棄該消息。
  2. 如果發生InstanceLockException(即 - 此工作流實例正在另一臺服務器上做某事),請將該消息放入重試隊列中。

我曾嘗試將TransactedReceiveScope放在接收活動周圍,但它會將消息放入相關錯誤的重試隊列中。另外,它在重負載下會導致很多問題。

沒有TransactedReceiveScope,如果存在InstanceLockException,則消息將被丟棄。

有沒有一種方法來實現這種行爲(也許通過行爲擴展)?

回答

1

您可以實現IErrorHandler for WCF來捕獲應用程序或WCF拋出的所有未處理的異常。用netMsmqBinding必須注意的一點是,在這個處理程序中拋出一個錯誤意味着該消息已被「成功」處理,並且將從隊列中取出。在發生InstanceLockException的情況下,如果您希望內置MSMQ 4重試處理髮生,您必須讓它保持未處理狀態。您還需要允許PoisonMessageException保持未處理狀態,以便正確執行MSMQ重試。

+0

這對我不起作用。我嘗試爲HandleException返回True,但消息始終放在重試隊列中。我認爲這個錯誤處理必須在流水線的早期被捕獲。 – Mas 2011-05-16 12:58:39

+0

這是WCF允許您處理異常的唯一一點,沒有其他擴展點。要發送信號給MSMQ,如果發生異常,並且您不希望重試,則表明消息已「成功」處理,則需要在適當命名的ProvideFault方法中提供FaultException。 MSMQ與WCF的交互不會讓您「拋棄」異常。順便說一句:HandleError方法的所有返回值都是告訴WCF這是最後一個調用的IErrorHandler,它對被捕獲的實際異常沒有影響。通常,HandleError僅用於異常記錄。 – 2011-05-16 13:25:43

+0

我已經實現了ProvideFault方法,並通過創建一個新的FaultException,faultException.CreateMessageFault(),fault = Message.CreateMessage來設置'ref Message fault'。但是,失敗的消息仍會進入重試隊列。是否有我需要創建的特殊類型的FaultException?我需要設置哪些字段? – Mas 2011-05-16 16:05:21

0

我不熟悉使用工作流,但知道如何MSMQ和WCF當CorrelationException發生的工作,你可以試試這個

  • 捕獲異常從服務方法
  • 返回

由於您的服務方法不會引發異常,它會認爲消息已成功處理並將其從隊列中刪除。

當InstanceLockException發生:

  • 捕獲異常
  • 重新拋出異常

由於您的服務方法拋出和異常它會認爲沒有成功處理郵件,並將其移到重試隊列。

+0

是的,但是,所有這些異常都發生在WCF管道內部,因此沒有機會去捕獲和處理這些異常。 – Mas 2011-05-12 15:48:16

0

我想你必須創建一個WCF自定義行爲來捕獲這些異常。

相關問題