1

我正在使用WCF服務來幫助我們的新代碼與舊系統進行互操作。該過程如下所示:WCF服務只有在客戶端收到結果時才寫入日誌

  1. 客戶端通過請求傳統系統來調用該服務。
  2. 服務將請求寫入數據庫。
  3. 傳統的系統服務請求從DB自己的時間,並寫入結果回數據庫(更新狀態標誌說結果準備)。
  4. 客戶端通過調用第二個服務方法來檢索結果,該方法輪詢數據庫,直到設置就緒標誌。
  5. 就在返回結果之前,服務將狀態標誌更新爲客戶端的結果爲,以便可以刪除相關的DB行。

我擔心的是最後一步的競賽狀況。我可以看到這樣的情況:

  1. 服務的更新狀態客戶端有結果
  2. 客戶端在等待服務輪詢數據庫後超時。
  3. 服務嘗試返回結果。歡鬧隨之而來。

解決此問題的一種方法是有三個服務調用而不是兩個:第二個調用檢索結果,最後一個是客戶端顯式確認它具有它們。我想知道是否有一種方法不會給客戶帶來額外的「協議」負擔。

我已經簡要介紹了在WCF中使用事務,聽起來他們可能能夠做我需要的事情。客戶端(可選)啓動一個事務,將其傳遞給服務,如果它存在,服務將使用它,並在完成時提交。這看起來好像它隱含地做了「第三次電話」。

這個想法有什麼優點嗎?你能看到什麼缺點?我還可以探索其他途徑嗎?

回答

1

使用事務流是可能的,但在輪詢場景中(在每個輪詢調用中)流動事務是可能的架構。您通常需要的是實際讀取操作的事務流,其中服務修改記錄並將數據返回給客戶端。客戶端將提交事務,並將提交該服務執行的更改。

使用事務處理對您的服務和客戶端提出了一些額外的要求。

另一種方法可以是事務MSMQ:

  1. 客戶端調用與用於傳統系統的請求的服務=客戶端將消息發送到該服務的隊列
  2. 服務請求寫入到數據庫=服務流程來自其隊列的消息
  3. 傳統系統服務請求從DB自己的時間,並將結果寫回DB(更新狀態標誌以表示結果已準備就緒)。
  4. 服務輪詢數據庫並將消息放置到正確的客戶端隊列。放置信息和修改的數據庫記錄在事務中運行
  5. 客戶處理傳入消息

事務隊列允許事務讀取(該消息被從僅當事務提交隊列中刪除)和寫入(該消息被加入到只有在提交事務時才允許隊列)。這將允許在客戶端讀取消息之前刪除記錄,因爲消息將保留在隊列中,直到他成功讀取它(或者直到它超時並且甚至在它可以傳遞給一些錯誤隊列之後)。

在這兩種情況下,您都應該考慮將使用該服務的客戶。事務流可以互操作,但並不是每個Web服務堆棧都支持它。 MSMQ不可互操作。

1

爲什麼不這樣做,而不是減少客戶端定時的可能性了:

  1. 客戶端調用服務與遺留系統的請求。
  2. 服務將請求寫入數據庫。
  3. 傳統的系統服務請求從DB自己的時間,並將結果寫回數據庫(更新狀態標誌,說結果已準備就緒)。
  4. 客戶端調用服務以確定結果是否已準備就緒。 NB。沒有輪詢:只是立即返回yes或no。
  5. 如果結果沒有準備好,客戶端會等待一會然後返回步驟4.
  6. 如果結果準備就緒,請調用服務以檢索結果。該服務可以將狀態更新爲「客戶有結果」

通過這樣做,客戶端將不會在第4步中等待服務調用以長時間返回,並且超時的機會應該很小。

但是,你永遠不會是100%肯定客戶端已收到結果,除非客戶端發出最後的服務調用這樣說。 (例如,如果客戶在發出最後一個請求後死亡,該怎麼辦?)

+0

感謝您的回答!對服務進行投票的理由是,只有一個地方可以制定調查數據庫的頻率政策,而不是將其交給個人客戶。如果我們部署並發現我們正在狠狠地抨擊它,那麼我們不需要推出數十或數百個客戶端更新。沒有人說這是做互操作的一種優雅的方式,唉:)你從來沒有100%肯定的觀點是好的,但交易(如果他們以我認爲他們這樣做的方式工作)具有超時的好處,並被回滾如果沒有承諾。 – shambulator

+0

@Anton:如果您擁有客戶端代碼,那麼您可以在調用(nother!)服務的客戶端中添加一些邏輯,以詢問客戶被允許調用「我的結果就緒」服務的頻率。通過這種方式,您仍然可以通過在一個地方(服務器端)更改閾值來限制客戶端調用;你不需要更新客戶端上的代碼來完成它。 – razlebe

+0

@Anton:另一個建議:服務器端的工作是否足夠可預測,以便您可以計算結果何時準備好的估計值,並將結果傳遞給客戶端(實際上,調度第一次客戶端調用結果)? – razlebe

相關問題