2010-06-10 37 views
9

假設您有一個連接3個不同外部系統的應用程序。您需要全部更新3.如果發生故障,您需要回滾操作。 這不是一件很難實現的事情,但是說操作3失敗了,當回滾時,操作1的回滾失敗!現在第一個外部系統處於無效狀態...幾個無交易外部系統的原子操作

我在想一個可能的解決方案是關閉應用程序並強制外部系統的手動修復,但後來又一次...它可能已經有了使用這些信息(也許這就是爲什麼它失敗了),或者我們可能沒有足夠的訪問權限。或者它可能不是一個回滾行動的好方法!

是否有一些好的方法來處理這種情況?

編輯:一些應用程序的細節..

這是一個多用戶的Web應用程序。大部分工作是通過預定的工作完成的(通過Quartz.Net),所以大多數操作都在它自己的線程中運行。某些用戶操作應觸發更新多個系統的作業。外部系統有些不穩定。

我想改變使用命令和機組工作模式

+0

外部系統是否固定?或者你可以修改它們嗎? – bmargulies 2010-06-14 04:38:39

回答

1

兩階段提交(2PC)可能適合此處。

第一階段是讓各種數據庫同意他們願意繼續提交。在你的例子中,數據庫1將不會繼續寫入,直到它確信所有三個數據庫都報告了事務可能。

與您所描述的過程相比,這是一種「樂觀」的方法 - 數據庫1將假定事務應該經過,直到它學習到了,否則將被迫回滾。

+0

謝謝。這有點像我已經使用UnitOfWork進行執行,提交和回滾,存儲具有CanProcess可執行和撤消的命令。 – simendsjo 2010-06-17 09:39:03

0

取決於應用(單個用戶對企業)的規模應用,關閉應用程序可能是一個壞主意。

首先,我建議將3個外部應用程序中要更改的信息的初始狀態保存到本地存儲到您自己的應用程序中。這意味着您至少可以確定應用程序崩潰/回滾失敗時應該執行的回滾狀態/ etc。一旦交易成功提交,您可以刪除這些數據。

當其中一個操作失敗時該怎麼辦取決於3個外部系統的功能。假設其中一個系統擁有員工數據。關閉應用程序僅僅是因爲一個員工的地址由於交易失敗而導致錯誤是矯枉過正的。只要訪問員工的數據,簡單地檢查失敗的事務日誌(即保存3個外部應用程序的初始狀態的本地存儲)就好多了。如果該僱員數據被標記爲無效,則拋出一個錯誤,指出該記錄處於無效狀態並且無法檢索。

但是,如果整個外部系統由於失敗的事務而陷入混亂,那麼是的 - 這裏沒有什麼可以做的,但是關閉應用程序直到問題得到解決。

1

您想進一步解釋操作1的回滾可能會失敗嗎?

它想要達到的狀態是之前的狀態,所以它應該在邏輯上一致。可能會出現網絡故障等暫時性問題,但最好的解決辦法就是重試,直到問題消失。

如果問題在於後續事務在此期間鎖定或更改了數據,那麼您遇到的問題要大得多 - 您的事務不是原子性的,並且將它們回滾可能導致其他事務的輸出失效。

0

Oddthinking的答案是一個好的,但有限,因爲它是很難可靠做一個2PC。這在分佈式計算社區中已經有很長一段時間了,儘管很多人都盡力忽略它。

如果您有興趣深入研究這個領域,Paxos consensus algorithm是一個很好的開始。並且要意識到,這是一個令人驚訝的難題,正是因爲你提到的兩個問題以及實際上不可能建立一個真正可靠的消息傳遞系統,它可以在有限的時間內傳遞消息。 (要理解爲什麼這是真的,考慮someone with a backhoe可能會消滅各通信方之間的所有網絡鏈接...)

我懷疑真正的修復是設計整個系統的體系結構以及如何在整個系統中推出更改一個地區的通信損失不是災難性的。這可能也可能不容易,具體取決於具體細節。