1 Saga相關(guān)概念
1987年普林斯頓大學(xué)的Hector Garcia-Molina和Kenneth Salem發(fā)表了一篇Paper Sagas,講述的是如何處理long lived transaction(長(zhǎng)活事務(wù))声搁。Saga是一個(gè)長(zhǎng)活事務(wù)可被分解成可以交錯(cuò)運(yùn)行的子事務(wù)集合泥从。其中每個(gè)子事務(wù)都是一個(gè)保持?jǐn)?shù)據(jù)庫(kù)一致性的真實(shí)事務(wù)。
論文地址:sagas
1.1 Saga的組成
- 每個(gè)Saga由一系列sub-transaction Ti 組成
- 每個(gè)Ti 都有對(duì)應(yīng)的補(bǔ)償動(dòng)作Ci,補(bǔ)償動(dòng)作用于撤銷Ti造成的結(jié)果
可以看到贩汉,和TCC相比盖桥,Saga沒有“預(yù)留”動(dòng)作,它的Ti就是直接提交到庫(kù)镊讼。
Saga的執(zhí)行順序有兩種:
- T1, T2, T3, ..., Tn
- T1, T2, ..., Tj, Cj,..., C2, C1宽涌,其中0 < j < n
Saga定義了兩種恢復(fù)策略:
- backward recovery,向后恢復(fù)蝶棋,補(bǔ)償所有已完成的事務(wù)卸亮,如果任一子事務(wù)失敗。即上面提到的第二種執(zhí)行順序玩裙,其中j是發(fā)生錯(cuò)誤的sub-transaction兼贸,這種做法的效果是撤銷掉之前所有成功的sub-transation,使得整個(gè)Saga的執(zhí)行結(jié)果撤銷吃溅。
- forward recovery溶诞,向前恢復(fù),重試失敗的事務(wù)决侈,假設(shè)每個(gè)子事務(wù)最終都會(huì)成功螺垢。適用于必須要成功的場(chǎng)景,執(zhí)行順序是類似于這樣的:T1, T2, ..., Tj(失敗), Tj(重試),..., Tn,其中j是發(fā)生錯(cuò)誤的sub-transaction甩苛。該情況下不需要Ci蹂楣。
顯然,向前恢復(fù)沒有必要提供補(bǔ)償事務(wù)讯蒲,如果你的業(yè)務(wù)中痊土,子事務(wù)(最終)總會(huì)成功,或補(bǔ)償事務(wù)難以定義或不可能墨林,向前恢復(fù)更符合你的需求赁酝。
理論上補(bǔ)償事務(wù)永不失敗,然而旭等,在分布式世界中酌呆,服務(wù)器可能會(huì)宕機(jī),網(wǎng)絡(luò)可能會(huì)失敗搔耕,甚至數(shù)據(jù)中心也可能會(huì)停電隙袁。在這種情況下我們能做些什么? 最后的手段是提供回退措施弃榨,比如人工干預(yù)菩收。
1.2 Saga的使用條件
Saga看起來很有希望滿足我們的需求。所有長(zhǎng)活事務(wù)都可以這樣做嗎鲸睛?這里有一些限制:
- Saga只允許兩個(gè)層次的嵌套娜饵,頂級(jí)的Saga和簡(jiǎn)單子事務(wù)
- 在外層,全原子性不能得到滿足官辈。也就是說箱舞,sagas可能會(huì)看到其他sagas的部分結(jié)果
- 每個(gè)子事務(wù)應(yīng)該是獨(dú)立的原子行為
- 在我們的業(yè)務(wù)場(chǎng)景下,各個(gè)業(yè)務(wù)環(huán)境(如:航班預(yù)訂拳亿、租車晴股、酒店預(yù)訂和付款)是自然獨(dú)立的行為,而且每個(gè)事務(wù)都可以用對(duì)應(yīng)服務(wù)的數(shù)據(jù)庫(kù)保證原子操作风瘦。
補(bǔ)償也有需考慮的事項(xiàng):
- 補(bǔ)償事務(wù)從語義角度撤消了事務(wù)Ti的行為队魏,但未必能將數(shù)據(jù)庫(kù)返回到執(zhí)行Ti時(shí)的狀態(tài)公般。(例如万搔,如果事務(wù)觸發(fā)導(dǎo)彈發(fā)射, 則可能無法撤消此操作)
但這對(duì)我們的業(yè)務(wù)來說不是問題官帘。其實(shí)難以撤消的行為也有可能被補(bǔ)償瞬雹。例如,發(fā)送電郵的事務(wù)可以通過發(fā)送解釋問題的另一封電郵來補(bǔ)償刽虹。
對(duì)于ACID的保證:
Saga對(duì)于ACID的保證和TCC一樣:
- 原子性(Atomicity):正常情況下保證酗捌。
- 一致性(Consistency),在某個(gè)時(shí)間點(diǎn),會(huì)出現(xiàn)A庫(kù)和B庫(kù)的數(shù)據(jù)違反一致性要求的情況胖缤,但是最終是一致的尚镰。
- 隔離性(Isolation),在某個(gè)時(shí)間點(diǎn)哪廓,A事務(wù)能夠讀到B事務(wù)部分提交的結(jié)果狗唉。
- 持久性(Durability),和本地事務(wù)一樣涡真,只要commit則數(shù)據(jù)被持久分俯。
Saga不提供ACID保證,因?yàn)樵有院透綦x性不能得到滿足哆料。原論文描述如下:
full atomicity is not provided. That is, sagas may view the partial results of other sagas
通過saga log缸剪,saga可以保證一致性和持久性。
和TCC對(duì)比
Saga相比TCC的缺點(diǎn)是缺少預(yù)留動(dòng)作东亦,導(dǎo)致補(bǔ)償動(dòng)作的實(shí)現(xiàn)比較麻煩:Ti就是commit杏节,比如一個(gè)業(yè)務(wù)是發(fā)送郵件,在TCC模式下典阵,先保存草稿(Try)再發(fā)送(Confirm)拢锹,撤銷的話直接刪除草稿(Cancel)就行了。而Saga則就直接發(fā)送郵件了(Ti)萄喳,如果要撤銷則得再發(fā)送一份郵件說明撤銷(Ci)卒稳,實(shí)現(xiàn)起來有一些麻煩。
如果把上面的發(fā)郵件的例子換成:A服務(wù)在完成Ti后立即發(fā)送Event到ESB(企業(yè)服務(wù)總線他巨,可以認(rèn)為是一個(gè)消息中間件)充坑,下游服務(wù)監(jiān)聽到這個(gè)Event做自己的一些工作然后再發(fā)送Event到ESB,如果A服務(wù)執(zhí)行補(bǔ)償動(dòng)作Ci染突,那么整個(gè)補(bǔ)償動(dòng)作的層級(jí)就很深捻爷。
不過沒有預(yù)留動(dòng)作也可以認(rèn)為是優(yōu)點(diǎn):
- 有些業(yè)務(wù)很簡(jiǎn)單,套用TCC需要修改原來的業(yè)務(wù)邏輯份企,而Saga只需要添加一個(gè)補(bǔ)償動(dòng)作就行了也榄。
- TCC最少通信次數(shù)為2n,而Saga為n(n=sub-transaction的數(shù)量)司志。
- 有些第三方服務(wù)沒有Try接口甜紫,TCC模式實(shí)現(xiàn)起來就比較tricky了,而Saga則很簡(jiǎn)單骂远。
- 沒有預(yù)留動(dòng)作就意味著不必?fù)?dān)心資源釋放的問題囚霸,異常處理起來也更簡(jiǎn)單(請(qǐng)對(duì)比Saga的恢復(fù)策略和TCC的異常處理)。
2 Saga相關(guān)實(shí)現(xiàn)
Saga Log
Saga保證所有的子事務(wù)都得以完成或補(bǔ)償激才,但Saga系統(tǒng)本身也可能會(huì)崩潰拓型。Saga崩潰時(shí)可能處于以下幾個(gè)狀態(tài):
- Saga收到事務(wù)請(qǐng)求额嘿,但尚未開始。因子事務(wù)對(duì)應(yīng)的微服務(wù)狀態(tài)未被Saga修改劣挫,我們什么也不需要做册养。
- 一些子事務(wù)已經(jīng)完成。重啟后压固,Saga必須接著上次完成的事務(wù)恢復(fù)捕儒。
- 子事務(wù)已開始,但尚未完成邓夕。由于遠(yuǎn)程服務(wù)可能已完成事務(wù)刘莹,也可能事務(wù)失敗,甚至服務(wù)請(qǐng)求超時(shí)焚刚,saga只能重新發(fā)起之前未確認(rèn)完成的子事務(wù)点弯。這意味著子事務(wù)必須冪等。
- 子事務(wù)失敗矿咕,其補(bǔ)償事務(wù)尚未開始抢肛。Saga必須在重啟后執(zhí)行對(duì)應(yīng)補(bǔ)償事務(wù)。
- 補(bǔ)償事務(wù)已開始但尚未完成碳柱。解決方案與上一個(gè)相同捡絮。這意味著補(bǔ)償事務(wù)也必須是冪等的。
- 所有子事務(wù)或補(bǔ)償事務(wù)均已完成莲镣,與第一種情況相同福稳。
為了恢復(fù)到上述狀態(tài),我們必須追蹤子事務(wù)及補(bǔ)償事務(wù)的每一步瑞侮。我們決定通過事件的方式達(dá)到以上要求的圆,并將以下事件保存在名為saga log的持久存儲(chǔ)中:
- Saga started event 保存整個(gè)saga請(qǐng)求,其中包括多個(gè)事務(wù)/補(bǔ)償請(qǐng)求
- Transaction started event 保存對(duì)應(yīng)事務(wù)請(qǐng)求
- Transaction ended event 保存對(duì)應(yīng)事務(wù)請(qǐng)求及其回復(fù)
- Transaction aborted event 保存對(duì)應(yīng)事務(wù)請(qǐng)求和失敗的原因
- Transaction compensated event 保存對(duì)應(yīng)補(bǔ)償請(qǐng)求及其回復(fù)
- Saga ended event 標(biāo)志著saga事務(wù)請(qǐng)求的結(jié)束半火,不需要保存任何內(nèi)容
通過將這些事件持久化在saga log中越妈,我們可以將saga恢復(fù)到上述任何狀態(tài)。
由于Saga只需要做事件的持久化钮糖,而事件內(nèi)容以JSON的形式存儲(chǔ)梅掠,Saga log的實(shí)現(xiàn)非常靈活,數(shù)據(jù)庫(kù)(SQL或NoSQL)店归,持久消息隊(duì)列阎抒,甚至普通文件可以用作事件存儲(chǔ), 當(dāng)然有些能更快得幫saga恢復(fù)狀態(tài)娱节。
注意事項(xiàng)
對(duì)于服務(wù)來說挠蛉,實(shí)現(xiàn)Saga有以下這些要求:
- Ti和Ci是冪等的祭示。
- Ci必須是能夠成功的肄满,如果無法成功則需要人工介入谴古。
- Ti - Ci和Ci - Ti的執(zhí)行結(jié)果必須是一樣的:sub-transaction被撤銷了。
第一點(diǎn)要求Ti和Ci是冪等的稠歉,舉個(gè)例子掰担,假設(shè)在執(zhí)行Ti的時(shí)候超時(shí)了,此時(shí)我們是不知道執(zhí)行結(jié)果的怒炸,如果采用forward recovery策略就會(huì)再次發(fā)送Ti带饱,那么就有可能出現(xiàn)Ti被執(zhí)行了兩次,所以要求Ti冪等阅羹。如果采用backward recovery策略就會(huì)發(fā)送Ci勺疼,而如果Ci也超時(shí)了,就會(huì)嘗試再次發(fā)送Ci捏鱼,那么就有可能出現(xiàn)Ci被執(zhí)行兩次执庐,所以要求Ci冪等。
第二點(diǎn)要求Ci必須能夠成功导梆,這個(gè)很好理解轨淌,因?yàn)椋绻鸆i不能執(zhí)行成功就意味著整個(gè)Saga無法完全撤銷看尼,這個(gè)是不允許的递鹉。但總會(huì)出現(xiàn)一些特殊情況比如Ci的代碼有bug、服務(wù)長(zhǎng)時(shí)間崩潰等藏斩,這個(gè)時(shí)候就需要人工介入了躏结。
第三點(diǎn)乍看起來比較奇怪,舉例說明狰域,還是考慮Ti執(zhí)行超時(shí)的場(chǎng)景窜觉,我們采用了backward recovery,發(fā)送一個(gè)Ci北专,那么就會(huì)有三種情況:
- Ti的請(qǐng)求丟失了禀挫,服務(wù)之前沒有、之后也不會(huì)執(zhí)行Ti
- Ti在Ci之前執(zhí)行
- Ci在Ti之前執(zhí)行
對(duì)于第1種情況拓颓,容易處理语婴。對(duì)于第2、3種情況驶睦,則要求Ti和Ci是可交換的(commutative)砰左,并且其最終結(jié)果都是sub-transaction被撤銷。
3 Saga協(xié)調(diào)
協(xié)調(diào)saga:saga的實(shí)現(xiàn)包含協(xié)調(diào)saga步驟的邏輯场航。當(dāng)系統(tǒng)命令啟動(dòng)saga時(shí)缠导,協(xié)調(diào)邏輯必須選擇并告知第一個(gè)saga參與者執(zhí)行本地事務(wù)。一旦該事務(wù)完成溉痢,saga的排序協(xié)調(diào)選擇并調(diào)用下一個(gè)saga參與者僻造。這個(gè)過程一直持續(xù)到saga執(zhí)行了所有步驟憋他。如果任何本地事務(wù)失敗,則saga必須以相反的順序執(zhí)行補(bǔ)償事務(wù)髓削。構(gòu)建一個(gè)saga的協(xié)調(diào)邏輯有幾種不同的方法:
- 編排(Choreography):在saga參與者中分配決策和排序竹挡。他們主要通過交換事件進(jìn)行溝通。
- 控制(Orchestration):在saga控制類中集中saga的協(xié)調(diào)邏輯立膛。一個(gè)saga控制者向saga參與者發(fā)送命令消息揪罕,告訴他們要執(zhí)行哪些操作。
3.1 編排(Choreography)
基于編排的saga:實(shí)現(xiàn)sagas的一種方法是使用編排宝泵。當(dāng)使用編排時(shí)好啰,沒有中央?yún)f(xié)調(diào)員告訴saga參與者該做什么。相反儿奶,sagas參與者訂閱彼此的事件并做出相應(yīng)的響應(yīng)坎怪。
通過這個(gè)sagas的路徑如下:
- Order Service在APPROVAL_PENDING狀態(tài)下創(chuàng)建一個(gè)Order并發(fā)布OrderCreated事件。
- Consumer Service消費(fèi)OrderCreated事件廓握,驗(yàn)證消費(fèi)者是否可以下訂單搅窿,并發(fā)布ConsumerVerified事件。
- Kitchen Service消費(fèi)OrderCreated事件隙券,驗(yàn)證訂單男应,在CREATE_PENDING狀態(tài)下創(chuàng)建故障單,并發(fā)布TicketCreated事件娱仔。
- Accounting服務(wù)消費(fèi)OrderCreated事件并創(chuàng)建一個(gè)處于PENDING狀態(tài)的Credit CardAuthorization沐飘。
- Accounting Service消費(fèi)TicketCreated和ConsumerVerified事件,收取消費(fèi)者的信用卡牲迫,并發(fā)布信用卡授權(quán)活動(dòng)耐朴。
- Kitchen Service使用CreditCardAuthorized事件并更改AWAITING_ACCEPTANCE票的狀態(tài)。
- Order Service收到CreditCardAuthorized事件盹憎,更改訂單狀態(tài)到APPROVED筛峭,并發(fā)布OrderApproved事件。
創(chuàng)建訂單saga還必須處理saga參與者拒絕訂單并發(fā)布某種失敗事件的場(chǎng)景陪每。例如影晓,消費(fèi)者信用卡的授權(quán)可能會(huì)失敗。saga必須執(zhí)行補(bǔ)償交易以撤消已經(jīng)完成的事情檩禾。圖中顯示了AccountingService無法授權(quán)消費(fèi)者信用卡時(shí)的事件流挂签。
事件順序如下:
- Order服務(wù)在APPROVAL_PENDING狀態(tài)下創(chuàng)建一個(gè)Order并發(fā)布OrderCreated事件。
- Consumer服務(wù)消費(fèi)OrderCreated事件盼产,驗(yàn)證消費(fèi)者是否可以下訂單饵婆,并發(fā)布ConsumerVerified事件。
- Kitchen服務(wù)消費(fèi)OrderCreated事件戏售,驗(yàn)證訂單侨核,在CREATE_PENDING狀態(tài)下創(chuàng)建故障單草穆,并發(fā)布TicketCreated事件。
- Accounting服務(wù)消費(fèi)OrderCreated事件并創(chuàng)建一個(gè)處于PENDING狀態(tài)的Credit CardAuthorization芹关。
- Accounting服務(wù)消費(fèi)TicketCreated和ConsumerVerified事件续挟,向消費(fèi)者的信用卡收費(fèi)紧卒,并發(fā)布信用卡授權(quán)失敗事件侥衬。
- Kitchen服務(wù)使用信用卡授權(quán)失敗事件并將故障單的狀態(tài)更改為REJECTED。
- 訂單服務(wù)消費(fèi)信用卡授權(quán)失敗事件跑芳,并將訂單狀態(tài)更改為已拒絕轴总。
可靠的基于事件的通信
在實(shí)施基于編排的saga時(shí),您必須考慮一些與服務(wù)間通信相關(guān)的問題博个。第一個(gè)問題是確保saga參與者更新其數(shù)據(jù)庫(kù)并將事件作為數(shù)據(jù)庫(kù)事務(wù)的一部分發(fā)布怀樟。
您需要考慮的第二個(gè)問題是確保saga參與者必須能夠?qū)⑹盏降拿總€(gè)事件映射到自己的數(shù)據(jù)。
編組的saga的好處和缺點(diǎn)
基于編舞的saga有幾個(gè)好處:
- 簡(jiǎn)單:服務(wù)在創(chuàng)建盆佣,更新或刪除業(yè)務(wù)時(shí)發(fā)布事件對(duì)象
- 松耦合:參與者訂閱事件并且彼此之間沒有直接的了解往堡。
并且有一些缺點(diǎn):
- 更難理解:與業(yè)務(wù)流程不同,代碼中沒有一個(gè)地方可以定義saga共耍。相反虑灰,編排在服務(wù)中分配saga的實(shí)現(xiàn)。因此痹兜,開發(fā)人員有時(shí)很難理解給定的saga是如何工作的穆咐。
- 服務(wù)之間的循環(huán)依賴關(guān)系:saga參與者訂閱彼此的事件,這通常會(huì)創(chuàng)建循環(huán)依賴關(guān)系字旭。例如对湃,如果仔細(xì)檢查圖示,您將看到存在循環(huán)依賴關(guān)系遗淳,例如訂單服務(wù)拍柒、會(huì)計(jì)服務(wù)、訂單服務(wù)屈暗。雖然這不一定是個(gè)問題斤儿,但循環(huán)依賴性被認(rèn)為是設(shè)計(jì)問題。
- 緊密耦合的風(fēng)險(xiǎn):每個(gè)saga參與者都需要訂閱所有影響他們的事件恐锦。例如往果,會(huì)計(jì)服務(wù)必須訂閱導(dǎo)致消費(fèi)者信用卡被收費(fèi)或退款的所有事件。因此一铅,存在一種風(fēng)險(xiǎn)陕贮,即需要與Order Service實(shí)施的訂單生命周期保持同步更新。
3.2 控制(Orchestration)
控制是實(shí)現(xiàn)sagas的另一種方式潘飘。使用業(yè)務(wù)流程時(shí)肮之,您可以定義一個(gè)控制類掉缺,其唯一的職責(zé)是告訴saga參與者該做什么。 saga控制使用命令/異步回復(fù)樣式交互與參與者進(jìn)行通信戈擒。
- Order Service首先創(chuàng)建一個(gè)Order和一個(gè)創(chuàng)建訂單控制器眶明。之后,路徑的流程如下:
- saga orchestrator向Consumer Service發(fā)送Verify Consumer命令筐高。
- Consumer Service回復(fù)Consumer Verified消息搜囱。
- saga orchestrator向Kitchen Service發(fā)送Create Ticket命令。
- Kitchen Service回復(fù)Ticket Created消息柑土。
- saga協(xié)調(diào)器向Accounting Service發(fā)送授權(quán)卡消息蜀肘。
- Accounting服務(wù)部門使用卡片授權(quán)消息回復(fù)。
- saga orchestrator向Kitchen Service發(fā)送Approve Ticket命令稽屏。
- saga orchestrator向訂單服務(wù)發(fā)送批準(zhǔn)訂單命令扮宠。
使用狀態(tài)機(jī)建模SAGA ORCHESTRATORS
建模saga orchestrator的好方法是作為狀態(tài)機(jī)。狀態(tài)機(jī)由一組狀態(tài)和一組由事件觸發(fā)的狀態(tài)之間的轉(zhuǎn)換組成狐榔。每個(gè)transition都可以有一個(gè)action坛增,對(duì)于一個(gè)saga來說是一個(gè)saga參與者的調(diào)用。狀態(tài)之間的轉(zhuǎn)換由saga參與者執(zhí)行的本地事務(wù)的完成觸發(fā)薄腻。當(dāng)前狀態(tài)和本地事務(wù)的特定結(jié)果決定了狀態(tài)轉(zhuǎn)換以及執(zhí)行的操作(如果有的話)收捣。對(duì)狀態(tài)機(jī)也有有效的測(cè)試策略。因此被廓,使用狀態(tài)機(jī)模型可以更輕松地設(shè)計(jì)坏晦、實(shí)施和測(cè)試。
圖顯示了Create Order Saga的狀態(tài)機(jī)模型嫁乘。此狀態(tài)機(jī)由多個(gè)狀態(tài)組成昆婿,包括以下內(nèi)容:
- Verifying Consumer:初始狀態(tài)。當(dāng)處于此狀態(tài)時(shí)蜓斧,該saga正在等待消費(fèi)者服務(wù)部門驗(yàn)證消費(fèi)者是否可以下訂單仓蛆。
- Creating Ticket:該saga正在等待對(duì)創(chuàng)建票證命令的回復(fù)。
- Authorizing Card:等待Accounting服務(wù)授權(quán)消費(fèi)者的信用卡挎春。
- OrderApproved:表示saga成功完成的最終狀態(tài)看疙。
- Order Rejected:最終狀態(tài)表明該訂單被其中一方參與者們拒絕。
SAGA ORCHESTRATION和TRANSACTIONAL MESSAGING
基于業(yè)務(wù)流程的saga的每個(gè)步驟都包括更新數(shù)據(jù)庫(kù)和發(fā)布消息的服務(wù)直奋。例如能庆,Order Service持久保存Order和Create Order Saga orchestrator,并向第一個(gè)saga參與者發(fā)送消息脚线。一個(gè)saga參與者搁胆,例如Kitchen Service,通過更新其數(shù)據(jù)庫(kù)并發(fā)送回復(fù)消息來處理命令消息。 Order Service通過更新saga協(xié)調(diào)器的狀態(tài)并向下一個(gè)saga參與者發(fā)送命令消息來處理參與者的回復(fù)消息渠旁。服務(wù)必須使用事務(wù)性消息傳遞攀例,以便自動(dòng)更新數(shù)據(jù)庫(kù)并發(fā)布消息。
讓我們來看看使用saga編排的好處和缺點(diǎn)顾腊。
基于ORCHESTRATION的SAGAS的好處和缺點(diǎn)
基于編排的saga有幾個(gè)好處:
- 更簡(jiǎn)單的依賴關(guān)系:編排的一個(gè)好處是它不會(huì)引入循環(huán)依賴關(guān)系粤铭。 saga orchestrator調(diào)用saga參與者,但參與者不會(huì)調(diào)用orchestrator杂靶。因此梆惯,協(xié)調(diào)器依賴于參與者,但反之亦然伪煤,因此沒有循環(huán)依賴性加袋。
- 較少的耦合:每個(gè)服務(wù)都實(shí)現(xiàn)了由orchestrator調(diào)用的API凛辣,因此它不需要知道saga參與者發(fā)布的事件抱既。
- 改善關(guān)注點(diǎn)分離并簡(jiǎn)化業(yè)務(wù)邏輯:saga協(xié)調(diào)邏輯本地化在saga協(xié)調(diào)器中。域?qū)ο蟾?jiǎn)單扁誓,并且不了解它們參與的saga防泵。例如,當(dāng)使用編排時(shí)蝗敢,Order類不知道任何saga捷泞,因此它具有更簡(jiǎn)單的狀態(tài)機(jī)模型。在執(zhí)行創(chuàng)建訂單saga期間寿谴,它直接從APPROVAL_PENDING狀態(tài)轉(zhuǎn)換到APPROVED狀態(tài)锁右。 Order類沒有與saga的步驟相對(duì)應(yīng)的任何中間狀態(tài)。因此讶泰,業(yè)務(wù)更加簡(jiǎn)單咏瑟。
業(yè)務(wù)流程也有一個(gè)缺點(diǎn):
- 在協(xié)調(diào)器中集中過多業(yè)務(wù)邏輯的風(fēng)險(xiǎn)。這導(dǎo)致了一種設(shè)計(jì)痪署,其中智能協(xié)調(diào)器告訴啞巴服務(wù)要做什么操作码泞。幸運(yùn)的是,您可以通過設(shè)計(jì)獨(dú)立負(fù)責(zé)排序的協(xié)調(diào)器來避免此問題狼犯,并且不包含任何其他業(yè)務(wù)邏輯余寥。
除了最簡(jiǎn)單的saga,我建議使用編排悯森。為您的saga實(shí)施協(xié)調(diào)邏輯只是您需要解決的設(shè)計(jì)問題之一宋舷。