2013-02-25 64 views
2

我的團隊有一個windows服務,它使用http綁定託管一個wcf服務。當wcf服務收到消息時,它會立即使用NetMsmqBinding將其發送到另一個wcf服務,該服務也駐留在Windows服務中。 msmq服務處理消息並將其保存到我們的數據庫中。NetMsmqBinding:郵件正在被多次處理

在開發和臨時環境中,一切正常。當我們部署到生產時,我們看到發送到我們服務的消息正乘以n + 1(對於n條消息)。

例如:收到1條消息,2條保存到數據庫。收到的4個消息,20保存到DB等

我們懷疑它是與交易的MSMQ服務設置,

併發,並InstanceContextMode,但我們不能弄明白。

服務的設置爲:

  • InstanceContextMode:默認。
  • ConcurrenyMode:默認
  • 事務:TransactionScoreRequired = True和TransactionAutoComplete = True。
  • RetryCount重= 1,RetryCycles = 1

我們使用.NET 4中,MSMQ 3.0和Windows Server 2003

任何想法,以什麼可能導致此問題?

編輯:

了大量的研究後,我們發現了以下幾件事:

  • 當WCF運行時嘗試提交事務的一個消息,它會拋出「交易異常異步中止「。每次消息重複時都會拋出此異常。
  • 在wcf跟蹤中,我們沒有看到任何異常,除了上面所述的異常。
  • 在System.Transaction跟蹤中,我們看到正在打開一個事務(針對第1條消息),然後在wcf運行時創建該事務的克隆(使用屬性RollbackIfNotCompleted = true)之後,幾秒鐘後通過跟蹤中沒有消息,然後同樣的事情再次發生。

我們真的無能......

感謝

回答

2

好了,我們終於得到了它: 我們使用Entlib用於記錄,並且我們添加了一個DB監聽器。 Entlib數據庫監聽器使用相同的服務事務。當它試圖將事務傳遞給數據庫服務器時,會引發錯誤,因爲數據庫服務器上的MSDTC配置不正確,導致事務回滾。當WCF運行時試圖提交事務時,它會因爲已經中止而失敗,然後它會嘗試再次處理相同的消息(因爲內置了重試機制)。

當我們修復MSDTC設置時,複製停止。
現在,我們需要弄清楚的是:爲什麼回滾到服務事務會導致消息倍增很多倍?

3

,除非您的程序中刪除或TimeToBeReceived計時器到期MSMQ不會刪除的消息。

如果我正確理解您的環境,您的問題可能是由於收到的消息的處理時間過長造成的。如果消息的接收和重新發送是在同一個事務中完成的,那麼在第一個WCF服務最終從隊列中刪除之前,它可能會嘗試多次讀取相同的消息。

這使我下面的想法,你可以嘗試:

  • 你可以嘗試,收到您的原始消息後,創建具有一樣的內容的新的消息,併發送新的下一WCF服務。這應該會縮短接收到的消息的生命週期。

  • 如果您需要保留的消息的順序相同,您可以嘗試Miker169的建議,更改配置爲InstanceContextMode.Single , ConcurrencyMode = ConcurrencyMode.Singlehttps://stackoverflow.com/a/2610093/219344