撤消由一系列步驟,它們共同限定了最終一致性操作中,如果一個(gè)或多個(gè)步驟失敗執(zhí)行的工作。按照最終一致性模型,業(yè)務(wù)實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)流程和工作流的云托管的應(yīng)用程序中很常見。
在云中運(yùn)行的應(yīng)用程序頻繁修改數(shù)據(jù)。此數(shù)據(jù)可跨在各種地理位置的所保持的數(shù)據(jù)源的一個(gè)品種傳播。為了避免爭(zhēng)用,并提高在分布式環(huán)境中,例如這樣的性能,應(yīng)用程序不應(yīng)該試圖提供強(qiáng)事務(wù)一致性。相反,應(yīng)用程序應(yīng)該實(shí)現(xiàn)最終一致性。在該模型中,一個(gè)典型的業(yè)務(wù)操作由一系列的獨(dú)立的步驟。而正在執(zhí)行這些步驟的系統(tǒng)狀態(tài)的整體圖可能是不一致的,但是,當(dāng)操作完成并且所有步驟都被執(zhí)行,系統(tǒng)應(yīng)該重新變得一致。
注意
數(shù)據(jù)的一致性提供了入門為什么分布式事務(wù)不能很好地?cái)U(kuò)展更多的信息,并且鞏固了最終一致性模型的原則。
在最終一致性模型的一個(gè)顯著的挑戰(zhàn)是如何處理失敗無(wú)可挽回的一步。在這種情況下,可能需要撤消所有通過(guò)的操作中的前面的步驟完成的工作。然而,數(shù)據(jù)不能簡(jiǎn)單地被回滾,因?yàn)閼?yīng)用程序的其它并發(fā)實(shí)例可能已經(jīng)改變,因?yàn)樗?。即使在?shù)據(jù)沒有被通過(guò)一并發(fā)實(shí)例變更的情況下,撤消一個(gè)步驟可能不是簡(jiǎn)單地恢復(fù)原始狀態(tài)的問題??赡苄枰獞?yīng)用不同的業(yè)務(wù)特定的規(guī)則(參見實(shí)施例部分中描述的旅行網(wǎng)站)。
如果實(shí)現(xiàn)最終一致性操作跨越多個(gè)異構(gòu)數(shù)據(jù)存儲(chǔ),解開在這樣的操作中的步驟將需要訪問的每個(gè)數(shù)據(jù)存儲(chǔ)區(qū)中的轉(zhuǎn)彎。在每一個(gè)數(shù)據(jù)存儲(chǔ)區(qū)執(zhí)行的工作必須可靠地復(fù)原到防止系統(tǒng)其余不一致。
不受實(shí)現(xiàn)最終一致性的操作的所有數(shù)據(jù)可能會(huì)在數(shù)據(jù)庫(kù)中進(jìn)行。在面向服務(wù)的架構(gòu)(SOA)環(huán)境中的操作可能會(huì)調(diào)用一個(gè)服務(wù)動(dòng)作,并導(dǎo)致由該服務(wù)保持狀態(tài)的變化。要撤消的操作,這種狀態(tài)的改變也必須是百?gòu)U待興。這可能涉及再次調(diào)用服務(wù)并執(zhí)行該反轉(zhuǎn)第一的影響另一個(gè)動(dòng)作。
落實(shí)補(bǔ)償事務(wù)。在一個(gè)補(bǔ)償事務(wù)的步驟必須撤消的原始操作的步驟的影響。補(bǔ)償事務(wù)可能無(wú)法簡(jiǎn)單地與國(guó)家的制度在運(yùn)行,因?yàn)檫@種方法可能會(huì)覆蓋由應(yīng)用程序的其他并發(fā)實(shí)例所做的更改開始取代目前的狀態(tài)。相反,它必須是一個(gè)聰明的過(guò)程中,考慮到并發(fā)情況下進(jìn)行的任何工作。這個(gè)過(guò)程通常是應(yīng)用程序特定的,由原始操作所執(zhí)行的工作的性質(zhì)來(lái)驅(qū)動(dòng)。
一種常見的方法來(lái)實(shí)現(xiàn)的,最終一致的操作,需要補(bǔ)償?shù)氖鞘褂玫墓ぷ髁?。由于原?lái)的動(dòng)作的進(jìn)行,系統(tǒng)記錄每個(gè)步驟,以及如何通過(guò)該步驟完成的工作可以撤消信息。如果操作失敗,在任何時(shí)候,在工作流倒卷回通過(guò)它已經(jīng)完成的步驟,并執(zhí)行反轉(zhuǎn)每個(gè)步驟的工作。注意,補(bǔ)償事務(wù)可能沒有撤消的原始操作的精確鏡面相反的順序工作,并且它可能會(huì)執(zhí)行一些并行撤銷步驟。
注意
這種方法類似于英雄傳奇策略。這一戰(zhàn)略的描述是克萊門斯 Vasters 的博客在網(wǎng)上提供。
補(bǔ)償事務(wù)本身是一個(gè)最終一致的操作,它也可能會(huì)失敗。該系統(tǒng)應(yīng)能夠恢復(fù)補(bǔ)償事務(wù)在故障點(diǎn)并繼續(xù)??赡苡斜匾貜?fù)發(fā)生故障的步驟,所以在補(bǔ)償事務(wù)的步驟應(yīng)該被定義為冪等的命令。有關(guān)冪等的詳細(xì)信息,請(qǐng)參閱喬納森·奧利弗的博客冪等模式??。
在某些情況下,可能無(wú)法從該已失敗,除非通過(guò)人工干預(yù)的步驟中恢復(fù)。在這種情況下,系統(tǒng)應(yīng)發(fā)出警報(bào),并提供盡可能多的信息盡可能了解失敗的原因。
在決定如何實(shí)現(xiàn)這個(gè)模式時(shí),請(qǐng)考慮以下幾點(diǎn):
注意: 很多的挑戰(zhàn)和實(shí)施補(bǔ)償事務(wù)的問題是一樣關(guān)心實(shí)現(xiàn)最終一致性。請(qǐng)參見注意事項(xiàng)實(shí)現(xiàn)了數(shù)據(jù)的一致性入門最終一致性的更多信息。
使用此模式僅適用于如果他們失敗,必須撤銷的操作。如果可能的話,設(shè)計(jì)解決方案,避免了需要補(bǔ)償事務(wù)的復(fù)雜性(有關(guān)詳細(xì)信息,請(qǐng)參閱數(shù)據(jù)一致性底漆)。
一個(gè)旅游網(wǎng)站,使客戶預(yù)訂行程。一個(gè)單一的行程可包括一系列航班和酒店的。一位顧客旅行從西雅圖到倫敦及巴黎可以創(chuàng)建一個(gè)行程時(shí),請(qǐng)執(zhí)行以下步驟:
1.預(yù)訂一個(gè)座位上的 F1 航班從西雅圖飛往倫敦。
2.預(yù)訂一個(gè)座位上的 F2 航班從倫敦到巴黎。
3.書本占座 F3 航班從巴黎飛往西雅圖。
4.預(yù)訂的房間在倫敦酒店 H1。
5.預(yù)訂在巴黎一間客房的酒店 H2。
這些步驟構(gòu)成了最終一致的操作,雖然每一步基本上是在自己的權(quán)利單獨(dú)的原子操作。因此,以及在執(zhí)行這些步驟時(shí),系統(tǒng)還必須記錄必要撤消各以防客戶決定取消行程步驟計(jì)數(shù)器的操作。必要執(zhí)行計(jì)數(shù)器操作步驟,然后可以作為一個(gè)補(bǔ)償事務(wù)如有必要運(yùn)行。
請(qǐng)注意,在補(bǔ)償事務(wù)中的步驟可能不是原來(lái)的步驟完全相反,并且在補(bǔ)償事務(wù)的每個(gè)步驟必須考慮到任何特定于業(yè)務(wù)的邏輯規(guī)則。例如,“unbooking 取消預(yù)訂”座位上的飛行可能不是客戶有權(quán)向支付任何款項(xiàng)完成退款。
圖1 - 生成一個(gè)補(bǔ)償事務(wù)撤消一個(gè)長(zhǎng)時(shí)間運(yùn)行的事務(wù)預(yù)訂旅游行程
它可能會(huì)在并行執(zhí)行的補(bǔ)償事務(wù)的步驟,這取決于你如何設(shè)計(jì)每一步的補(bǔ)償邏輯。
在許多商業(yè)解決方案,在單步的故障不總是必要軋制系統(tǒng)背面用補(bǔ)償事務(wù)。例如,具有在旅游網(wǎng)站的情況,客戶是無(wú)法預(yù)訂到酒店H1預(yù)訂航班 F1,F(xiàn)2 和 F3 的話,以后,最好是提供客戶在同一個(gè)城市的房間在不同的酒店而不是取消航班??蛻羧匀豢梢赃x擇取消(在這種情況下,補(bǔ)償事務(wù)運(yùn)行,并撤消作出關(guān)于航班 F1,F(xiàn)2 和 F3中的預(yù)訂),但這個(gè)決定應(yīng)該由客戶而不是由系統(tǒng)進(jìn)行。
更多建議: