一、what
??????? 分布式事務(wù)是指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點(diǎn)之上。
二、CAP原理
??????? C-consistency一致性,A-availability可用性,P-partition tolerance分區(qū)容錯(cuò)性。CAP 原則指的是,這三個(gè)要素最多只能同時(shí)實(shí)現(xiàn)兩點(diǎn),不可能三者兼顧。
??????? 因?yàn)榉植际较到y(tǒng)中系統(tǒng)肯定部署在多臺(tái)機(jī)器上,無(wú)法保證網(wǎng)絡(luò)做到100%的可靠,所以網(wǎng)絡(luò)分區(qū)一定存在,即P一定存在;就出現(xiàn)了可用性和一致性的問(wèn)題,我們必須要在這兩者之間進(jìn)行取舍,因此就有了兩種架構(gòu):CP架構(gòu),AP架構(gòu)。
三、相關(guān)協(xié)議
??????? 解決分布式事務(wù),也有相應(yīng)的規(guī)范和協(xié)議。分布式事務(wù)相關(guān)的協(xié)議有2PC、3PC。由于三階段提交協(xié)議3PC非常難實(shí)現(xiàn),目前市面主流的分布式事務(wù)解決方案都是2PC協(xié)議。
1.2PC兩階段提交協(xié)議(Two-Phase Commit)
??????? 第一階段:所有事務(wù)參與者,執(zhí)行后進(jìn)行預(yù)提交;直到協(xié)調(diào)者收到所有參與者的預(yù)提交才會(huì)進(jìn)入第二步;
??????? 第二階段:所有事務(wù)預(yù)提交了各自的結(jié)果后,由協(xié)調(diào)者決定最終事務(wù)是成功(commit)還是失敗(rollback)。

??????? 問(wèn)題
??????? 1) 性能問(wèn)題:所有參與者在事務(wù)提交階段處于同步阻塞狀態(tài),占用系統(tǒng)資源,容易導(dǎo)致性能瓶頸。
??????? 2) 可靠性問(wèn)題:如果協(xié)調(diào)者存在單點(diǎn)故障問(wèn)題,或出現(xiàn)故障,提供者將一直處于鎖定狀態(tài)。
??????? 3) 數(shù)據(jù)一致性問(wèn)題:在階段 2 中,如果出現(xiàn)協(xié)調(diào)者和參與者都掛了的情況,有可能導(dǎo)致數(shù)據(jù)不一致。
??????? 優(yōu)點(diǎn):盡量保證了數(shù)據(jù)的強(qiáng)一致,適合對(duì)數(shù)據(jù)強(qiáng)一致要求很高的關(guān)鍵領(lǐng)域。(其實(shí)也不能100%保證強(qiáng)一致)。
??????? 缺點(diǎn):犧牲了可用性,對(duì)性能影響較大,不大適合高并發(fā)高性能場(chǎng)景。
2.3PC三階段提交協(xié)議(Three-Phase Commit)
??????? 與兩階段提交不同的是,三階段提交是“非阻塞”協(xié)議。三階段提交在兩階段提交的第一階段與第二階段之間插入了一個(gè)準(zhǔn)備階段,使得原先在兩階段提交中,參與者在投票之后,由于協(xié)調(diào)者發(fā)生崩潰或錯(cuò)誤,而導(dǎo)致參與者處于無(wú)法知曉是否提交或者中止的“不確定狀態(tài)”所產(chǎn)生的可能相當(dāng)長(zhǎng)的延時(shí)的問(wèn)題得以解決。

四、兩階段提交的四種模式
1.AT模式???
???? ???? AT 模式是一種無(wú)侵入的分布式事務(wù)解決方案(阿里seata框架,實(shí)現(xiàn)了該模式)。
???? ???? 在 AT 模式下,用戶只需關(guān)注自己的“業(yè)務(wù) SQL”,用戶的 “業(yè)務(wù) SQL”?作為一階段,Seata 框架會(huì)自動(dòng)生成事務(wù)的二階段提交和回滾操作。
???? ???? 在一階段,Seata 會(huì)攔截“業(yè)務(wù) SQL”,首先解析 SQL 語(yǔ)義,找到“業(yè)務(wù) SQL”要更新的業(yè)務(wù)數(shù)據(jù),在業(yè)務(wù)數(shù)據(jù)被更新前,將其保存成“before image”,然后執(zhí)行“業(yè)務(wù)SQL”更新業(yè)務(wù)數(shù)據(jù),在業(yè)務(wù)數(shù)據(jù)更新之后,再將其保存成“after image”,最后生成行鎖。以上操作全部在seata自己的一個(gè)數(shù)據(jù)庫(kù)事務(wù)內(nèi)完成,這樣保證了一階段操作的原子性。
???? ???? 二階段如果是提交的話,因?yàn)椤皹I(yè)務(wù) SQL”在一階段已經(jīng)提交至數(shù)據(jù)庫(kù), 所以 Seata 框架只需將一階段保存的快照數(shù)據(jù)和行鎖刪掉,完成數(shù)據(jù)清理即可。
???? ???? 二階段如果是回滾的話,Seata 就需要回滾一階段已經(jīng)執(zhí)行的“業(yè)務(wù) SQL”,還原業(yè)務(wù)數(shù)據(jù)。回滾方式便是用“before image”還原業(yè)務(wù)數(shù)據(jù);但在還原前要首先要校驗(yàn)臟寫(xiě),對(duì)比“數(shù)據(jù)庫(kù)當(dāng)前業(yè)務(wù)數(shù)據(jù)”和 “after image”,如果兩份數(shù)據(jù)完全一致就說(shuō)明沒(méi)有臟寫(xiě),可以還原業(yè)務(wù)數(shù)據(jù),如果不一致就說(shuō)明有臟寫(xiě),出現(xiàn)臟寫(xiě)就需要轉(zhuǎn)人工處理。
2.TCC 模式 ????
???? ???? TCC 模式需要用戶根據(jù)自己的業(yè)務(wù)場(chǎng)景實(shí)現(xiàn) Try、Confirm 和 Cancel 三個(gè)操作;事務(wù)發(fā)起方在一階段執(zhí)行 Try 方式,在二階段提交執(zhí)行 Confirm 方法,二階段回滾執(zhí)行 Cancel 方法。???
???? ???? Try:資源的檢測(cè)和預(yù)留;
???? ???? Confirm:執(zhí)行的業(yè)務(wù)操作提交;要求 Try 成功 Confirm 一定要能成功;
???? ???? Cancel:預(yù)留資源釋放;

???? ????

3.saga模式

????????? 分布式事務(wù)執(zhí)行過(guò)程中,依次執(zhí)行各參與者的正向操作,如果所有正向操作均執(zhí)行成功,那么分布式事務(wù)提交。如果任何一個(gè)正向操作執(zhí)行失敗,那么分布式事務(wù)會(huì)退回去執(zhí)行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務(wù)回到初始狀態(tài)。
????????? Saga 正向服務(wù)與補(bǔ)償服務(wù)也需要業(yè)務(wù)開(kāi)發(fā)者實(shí)現(xiàn)。因此是業(yè)務(wù)入侵的。
????????? Saga 模式下分布式事務(wù)通常是由事件驅(qū)動(dòng)的,各個(gè)參與者之間是異步執(zhí)行的,Saga 模式是一種長(zhǎng)事務(wù)解決方案。
優(yōu)勢(shì):
????????? 一階段提交本地?cái)?shù)據(jù)庫(kù)事務(wù),無(wú)鎖,高性能;
????????? 參與者可以采用事務(wù)驅(qū)動(dòng)異步執(zhí)行,高吞吐;
????????? 補(bǔ)償服務(wù)即正向服務(wù)的“反向”,易于理解,易于實(shí)現(xiàn);
缺點(diǎn):
????????? Saga 模式由于一階段已經(jīng)提交本地?cái)?shù)據(jù)庫(kù)事務(wù),且沒(méi)有進(jìn)行“預(yù)留”動(dòng)作,所以不能保證隔離性。
4.XA模式
???????? XA被許多數(shù)據(jù)庫(kù)(如Oracle、DB2、SQL Server、MySQL)和中間件等工具(如CICS 和 Tuxedo)本地支持 。JTA(Java Transaction API) 是Java實(shí)現(xiàn)的XA規(guī)范的增強(qiáng)版 接口。
???????? 在XA模式下,需要有一個(gè)[全局]協(xié)調(diào)器,每一個(gè)數(shù)據(jù)庫(kù)事務(wù)完成后,進(jìn)行第一階段預(yù)提交,并通知協(xié)調(diào)器,把結(jié)果給協(xié)調(diào)器。協(xié)調(diào)器等所有分支事務(wù)操作完成、都預(yù)提交后,進(jìn)行第二步;第二步:協(xié)調(diào)器通知每個(gè)數(shù)據(jù)庫(kù)進(jìn)行逐個(gè)commit/rollback。
5.每種模式都有它的適用場(chǎng)景
? ? AT 模式是無(wú)侵入的分布式事務(wù)解決方案,適用于不希望對(duì)業(yè)務(wù)進(jìn)行改造的場(chǎng)景,幾乎0學(xué)習(xí)成本。
? ? TCC 模式是高性能分布式事務(wù)解決方案,適用于核心系統(tǒng)等對(duì)性能有很高要求的場(chǎng)景。
? ? Saga 模式是長(zhǎng)事務(wù)解決方案,適用于業(yè)務(wù)流程長(zhǎng)且需要保證事務(wù)最終一致性的業(yè)務(wù)系統(tǒng),Saga 模式一階段就會(huì)提交本地事務(wù),無(wú)鎖,長(zhǎng)流程情況下可以保證性能,多用于渠道層、集成層業(yè)務(wù)系統(tǒng)。事務(wù)參與者可能是其它公司的服務(wù)或者是遺留系統(tǒng)的服務(wù),無(wú)法進(jìn)行改造和提供 TCC 要求的接口,也可以使用 Saga 模式。
? ? XA模式是分布式強(qiáng)一致性的解決方案,但性能低而使用較少。
五、解決方案
1.強(qiáng)一致性:
????????? seata 阿里分布式事務(wù)框架(支持AT 、TCC、Saga 、XA)
2.最終一致性:
a.本地消息表:

優(yōu)點(diǎn):?一種非常經(jīng)典的實(shí)現(xiàn),避免了分布式事務(wù),實(shí)現(xiàn)了最終一致性。
缺點(diǎn):?消息表會(huì)耦合到業(yè)務(wù)系統(tǒng)中,如果沒(méi)有封裝好的解決方案,會(huì)有很多雜活需要處理。
b.MQ消息事務(wù)

有一些第三方的MQ是支持事務(wù)消息的,比如RocketMQ,但是市面上一些主流的MQ都是不支持事務(wù)消息的,比如 RabbitMQ 和 Kafka 都不支持。
執(zhí)行流程:
1.發(fā)送prepare消息到消息中間件
2.發(fā)送成功后,執(zhí)行本地事務(wù)
3.如果事務(wù)執(zhí)行成功,則commit,消息中間件將消息下發(fā)至消費(fèi)端
4.如果事務(wù)執(zhí)行失敗,則回滾,消息中間件將這條prepare消息刪除
5.如果確認(rèn)消息發(fā)送失敗了RocketMQ會(huì)定期掃描消息集群中的事務(wù)消息,這時(shí)候發(fā)現(xiàn)了Prepared消息,它會(huì)向消息發(fā)送者確認(rèn),所以生產(chǎn)方需要實(shí)現(xiàn)一個(gè)check接口,RocketMQ會(huì)根據(jù)發(fā)送端設(shè)置的策略來(lái)決定是回滾還是繼續(xù)發(fā)送確認(rèn)消息。這樣就保證了消息發(fā)送與本地事務(wù)同時(shí)成功或同時(shí)失敗。
6.消費(fèi)端接收到消息進(jìn)行消費(fèi),如果消費(fèi)失敗,則不斷重試。
這種方案也是實(shí)現(xiàn)了最終一致性,對(duì)比本地消息表實(shí)現(xiàn)方案,不需要再建消息表,不再依賴(lài)本地?cái)?shù)據(jù)庫(kù)事務(wù)了,所以這種方案更適用于高并發(fā)的場(chǎng)景。
c.最大努力通知
????????? 最大努力通知相比前兩種方案實(shí)現(xiàn)簡(jiǎn)單,適用于一些最終一致性要求較低的業(yè)務(wù),比如支付通知,短信通知這種業(yè)務(wù)。
?????? 以支付通知為例,業(yè)務(wù)系統(tǒng)調(diào)用支付平臺(tái)進(jìn)行支付,支付平臺(tái)進(jìn)行支付,進(jìn)行操作支付之后支付平臺(tái)會(huì)盡量去通知業(yè)務(wù)系統(tǒng)支付操作是否成功,但是會(huì)有一個(gè)最大通知次數(shù),如果超過(guò)這個(gè)次數(shù)后還是通知失敗,就不再通知,業(yè)務(wù)系統(tǒng)自行調(diào)用支付平臺(tái)提供一個(gè)查詢接口,供業(yè)務(wù)系統(tǒng)進(jìn)行查詢支付操作是否成功。