oledb 访问接口sqlncli10返回了消息 没有活动事务_这样理解分布式事务你是不是就会懂了?...
分布式事務(wù)主要解決分布式一致性的問(wèn)題。說(shuō)到底就是數(shù)據(jù)的分布式操作導(dǎo)致僅依靠本地事務(wù)無(wú)法保證原的性。與單機(jī)版的事務(wù)不同的是,單機(jī)是把多個(gè)命令打包成一個(gè)統(tǒng)一處理,分布式事務(wù)是將多個(gè)機(jī)器上執(zhí)行的命令打包成一個(gè)命令統(tǒng)一處理。
常見(jiàn)的分布式事務(wù)場(chǎng)景#
分布式事務(wù)其實(shí)就在我們身邊,你一直在用,但是你卻一直不注意它。
轉(zhuǎn)賬
扣你賬戶的余額,增加別人賬戶余額,如果只扣了你的,別人沒(méi)增加這是失敗;如果沒(méi)扣你的錢(qián)別人也增加了那銀行的賠錢(qián)。
下訂單/扣庫(kù)存
電商系統(tǒng)中這是很常見(jiàn)的一個(gè)場(chǎng)景,用戶下單成功了,店家沒(méi)收到單,不發(fā)貨;用戶取消了訂單,但是店家卻看到了訂單,發(fā)了貨。
分庫(kù)分表場(chǎng)景
當(dāng)我們的數(shù)據(jù)量大了之后,我們可能會(huì)部署很多獨(dú)立的數(shù)據(jù)庫(kù),但是你的一個(gè)邏輯可能會(huì)同時(shí)操作很多個(gè)數(shù)據(jù)庫(kù)的表,這時(shí)候該如何保證所有的操作要么成功,要么失敗。
分布式系統(tǒng)調(diào)用問(wèn)題
微服務(wù)的拆分讓各個(gè)系統(tǒng)各司其職,但是帶來(lái)的也有很多痛苦,一個(gè)操作可能會(huì)伴隨很多的外部請(qǐng)求,如果某一個(gè)外部系統(tǒng)掛掉了,之前操作已完成的這些是否需要回滾。
針對(duì)上面這些問(wèn)題,我們前面學(xué)過(guò)的數(shù)據(jù)庫(kù)4大特性:ACID 似乎在這里想要達(dá)到就變得很困難,單機(jī)情況下你還可以通過(guò)鎖和日志機(jī)制來(lái)控制數(shù)據(jù),在分布式場(chǎng)景又該如何實(shí)現(xiàn)呢?在不同的分布式應(yīng)用架構(gòu)下,實(shí)現(xiàn)一個(gè)分布式事務(wù)要考慮的問(wèn)題并不完全一樣,比如對(duì)多資源的協(xié)調(diào)、事務(wù)的跨服務(wù)傳播等,實(shí)現(xiàn)機(jī)制也是復(fù)雜多變。盡管有這么多工程細(xì)節(jié)需要考慮,但分布式事務(wù)最核心的還是其 ACID 特性,只是這種 ACID 變換了場(chǎng)景。
分布式理論#
CAP 定理
傳統(tǒng)的 ACID 模型肯定無(wú)法解決分布式環(huán)境下的挑戰(zhàn),基于此加州大學(xué)伯克利分校 Eric Brewer教授提出 CAP 定理,他指出 現(xiàn)代 WEB 服務(wù)無(wú)法同時(shí)滿足以下 3 個(gè)屬性:
- 一致性(Consistency) : 所有的客戶端都能返回最新的操作。
- 可用性(Availability) : 非故障的節(jié)點(diǎn)在合理的時(shí)間內(nèi)返回合理的響應(yīng)(不是錯(cuò)誤和超時(shí)的響應(yīng))。
- 分區(qū)容錯(cuò)性(Partition tolerance) : 即使出現(xiàn)單個(gè)組件無(wú)法可用,操作依然可以完成。
關(guān)于一致性的理解后面分出來(lái)三個(gè)方向:
- 強(qiáng)一致:任何一次讀都能讀到某個(gè)數(shù)據(jù)的最近一次寫(xiě)的數(shù)據(jù)。系統(tǒng)中的所有進(jìn)程,看到的操作順序,都和全局時(shí)鐘下的順序一致。簡(jiǎn)言之,在任意時(shí)刻,所有節(jié)點(diǎn)中的數(shù)據(jù)是一樣的。
- 弱一致:數(shù)據(jù)更新后,如果能容忍后續(xù)的訪問(wèn)只能訪問(wèn)到部分或者全部訪問(wèn)不到,則是弱一致性。
- 最終一致:不保證在任意時(shí)刻任意節(jié)點(diǎn)上的同一份數(shù)據(jù)都是相同的,但是隨著時(shí)間的遷移,不同節(jié)點(diǎn)上的同一份數(shù)據(jù)總是在向不同的方向變化。簡(jiǎn)單說(shuō),就是在一段時(shí)間后,節(jié)點(diǎn)間的數(shù)據(jù)會(huì)最終達(dá)到一致?tīng)顟B(tài)。
關(guān)于一致性的理解不同,后面對(duì)于 CAP 理論的實(shí)現(xiàn)就有所不同。
另外 Eric Brewer教授指出現(xiàn)代 WEB 服務(wù)無(wú)法同時(shí)滿足這 3 個(gè)屬性,說(shuō)的是無(wú)法同時(shí)滿足,那這是為什么呢?
如果在某個(gè)分布式系統(tǒng)中無(wú)副本,那么必然滿足強(qiáng)一致性,同時(shí)也滿足可用性,但是如果這個(gè)數(shù)據(jù)宕機(jī)了,那么可用性就得不到保證。
如果一個(gè)系統(tǒng)滿足 AP,那么一致性又得不到保證。所以 CAP 原則的精髓就是要么 AP,要么 CP,要么 AC,但是不存在 CAP。
BASE 定理
基于前面提到的 CAP,反正我們都無(wú)法同時(shí)滿足CAP,設(shè)計(jì)系統(tǒng)的最高目的就是讓他跑下去不出錯(cuò),那么是不是可以不要求強(qiáng)一致性,最終讓他一致即可。所以后面又提出來(lái)了 BASE 定理:
- Basically Available(基本可用)
- Soft state(軟狀態(tài))
- Eventually consistent(最終一致性)
基于現(xiàn)在大型分布式系統(tǒng)的復(fù)雜性,我們無(wú)法保證服務(wù)永遠(yuǎn)達(dá)到999,那么是否可以取舍,核心服務(wù)達(dá)到999,非核心服務(wù)允許掛為了保全核心服務(wù)。另外在非核心服務(wù) down 機(jī)過(guò)程中允許系統(tǒng)暫時(shí)出現(xiàn)不一致但是這個(gè)不一致并不影響系統(tǒng)的核心功能使用。
最終系統(tǒng)恢復(fù),所有服務(wù)一起修復(fù)數(shù)據(jù),最終達(dá)到一致的狀態(tài)。
業(yè)內(nèi)通常把嚴(yán)格遵循 ACID 的事務(wù)稱為剛性事務(wù),而基于 BASE 思想實(shí)現(xiàn)的事務(wù)稱為柔性事務(wù)。柔性事務(wù)并不是完全放棄了 ACID,僅僅是放寬了一致性要求:事務(wù)完成后的一致性嚴(yán)格遵循,事務(wù)中的一致性可適當(dāng)放寬。
常見(jiàn)的分布式事務(wù)實(shí)現(xiàn)方案#
分布式事務(wù)實(shí)現(xiàn)方案從類型上區(qū)分剛性事務(wù)、柔性事務(wù)。剛性事務(wù):通常無(wú)業(yè)務(wù)改造,強(qiáng)一致性,原生支持回滾/隔離性,低并發(fā),適合短事務(wù)。柔性事務(wù):有業(yè)務(wù)改造,最終一致性,實(shí)現(xiàn)補(bǔ)償接口,實(shí)現(xiàn)資源鎖定接口,高并發(fā),適合長(zhǎng)事務(wù)。
- 剛性事務(wù):XA 協(xié)議(2PC、JTA、JTS)、3PC
- 柔性事務(wù):TCC/FMT、Saga(狀態(tài)機(jī)模式、Aop模式)、本地事務(wù)消息、消息事務(wù)(半消息)、最多努力通知型事務(wù)
兩階段提交(XA)
與本地事務(wù)一樣,分布式事務(wù)場(chǎng)景下也可以采用兩階段提交的方案來(lái)實(shí)現(xiàn)。XA 的全稱是 eXtended Architecture,它是一個(gè)分布式事務(wù)協(xié)議,通過(guò)二階段提交協(xié)議保證強(qiáng)一致性。
XA 規(guī)范中定義了分布式事務(wù)處理模型,這個(gè)模型中包含四個(gè)核心角色:
- RM (Resource Managers):資源管理器,提供數(shù)據(jù)資源的操作、管理接口,保證數(shù)據(jù)的一致性和完整性。最有代表性的就是數(shù)據(jù)庫(kù)管理系統(tǒng),當(dāng)然有的文件系統(tǒng)、MQ 系統(tǒng)也可以看作 RM。
- TM (Transaction Managers):事務(wù)管理器,是一個(gè)協(xié)調(diào)者的角色,協(xié)調(diào)跨庫(kù)事務(wù)關(guān)聯(lián)的所有 RM 的行為。
- AP (Application Program):應(yīng)用程序,按照業(yè)務(wù)規(guī)則調(diào)用 RM 接口來(lái)完成對(duì)業(yè)務(wù)模型數(shù)據(jù)的變更,當(dāng)數(shù)據(jù)的變更涉及多個(gè) RM 且要保證事務(wù)時(shí),AP 就會(huì)通過(guò) TM 來(lái)定義事務(wù)的邊界,TM 負(fù)責(zé)協(xié)調(diào)參與事務(wù)的各個(gè) RM 一同完成一個(gè)全局事務(wù)。
- CRMs (Communication Resource Managers):主要用來(lái)進(jìn)行跨服務(wù)的事務(wù)的傳播。
XA 協(xié)議大概的兩個(gè)流程為:
XA 協(xié)議是如何滿足 ACID 的呢?
原的性和持久性我們就不用說(shuō),我們看看隔離性和一致性。
隔離性
XA 協(xié)議中沒(méi)有描述如何實(shí)現(xiàn)分布式事務(wù)的隔離性,但是 XA 協(xié)議要求每個(gè)資源管理器都要實(shí)現(xiàn)本地事務(wù),也就是說(shuō)基于 XA 協(xié)議實(shí)現(xiàn)的分布式事務(wù)的隔離性是由每個(gè)資源管理器本地事務(wù)的隔離性來(lái)保證的,當(dāng)一個(gè)分布式事務(wù)的所有子事務(wù)都是隔離的,那么這個(gè)分布式事務(wù)天然的就實(shí)現(xiàn)了隔離性。
一致性
在單機(jī)環(huán)境下的一致性就是保證當(dāng)前服務(wù)器數(shù)據(jù)一致即可。事務(wù)執(zhí)行完畢數(shù)據(jù)最終一致,不同的隔離級(jí)別下事務(wù)執(zhí)行過(guò)程的中間狀態(tài)不能被別的事務(wù)觀察到。
事務(wù)執(zhí)行完畢最終一致這個(gè)好保證,但是在RR 隔離級(jí)別下不可見(jiàn)一個(gè)未提交事務(wù)的中間態(tài)在分布式情況該如何做到呢?單機(jī)上 MySQL 提供了MVCC機(jī)制,采用多版本控制來(lái)處理,那分布式事務(wù)場(chǎng)景也是否也可以提供這樣的機(jī)制呢?XA 協(xié)議并沒(méi)有定義怎么實(shí)現(xiàn)全局的快照,一個(gè)基本思路是用一個(gè)集中式或者邏輯上單調(diào)遞增的東西來(lái)控制生成全局 Snapshot,每個(gè)事務(wù)或者每條 SQL 執(zhí)行時(shí)都去獲取一次,從而實(shí)現(xiàn)不同隔離級(jí)別下的一致性。當(dāng)然開(kāi)發(fā)的難度還是挺大。
存在的問(wèn)題:
- 同步阻塞:當(dāng)參與事務(wù)者存在占用公共資源的情況,其中一個(gè)占用了資源,其他事務(wù)參與者就只能阻塞等待資源釋放,處于阻塞狀態(tài)。
- 單點(diǎn)故障:一旦事務(wù)管理器出現(xiàn)故障,整個(gè)系統(tǒng)不可用。
- 數(shù)據(jù)不一致:在階段二,如果事務(wù)管理器只發(fā)送了部分 commit 消息,此時(shí)網(wǎng)絡(luò)發(fā)生異常,那么只有部分參與者接收到 commit 消息,也就是說(shuō)只有部分參與者提交了事務(wù),使得系統(tǒng)數(shù)據(jù)不一致。
- 不確定性:當(dāng)事務(wù)管理器發(fā)送 commit 之后,并且此時(shí)只有一個(gè)參與者收到了 commit,那么當(dāng)該參與者與事務(wù)管理器同時(shí)宕機(jī)之后,重新選舉的事務(wù)管理器無(wú)法確定該條消息是否提交成功。
總體來(lái)說(shuō) XA 方案實(shí)現(xiàn)簡(jiǎn)單,但是帶來(lái)的問(wèn)題如果放在數(shù)據(jù)一致性要求嚴(yán)格的場(chǎng)景是無(wú)法保證數(shù)據(jù)正確性的。另外事務(wù)管理器單點(diǎn)會(huì)帶來(lái)隱患,同步阻塞模型也致使并發(fā)能力弱。
TCC
關(guān)于 TCC(Try-Confirm-Cancel)的概念,最早是由 Pat Helland 于 2007 年發(fā)表的一篇名為《Life beyond Distributed Transactions:an Apostate’s Opinion》的論文提出。 TCC 事務(wù)機(jī)制相比于上面介紹的 XA,解決了其幾個(gè)缺點(diǎn):
TCC 其實(shí)就是采用的補(bǔ)償機(jī)制,其核心思想是:針對(duì)每個(gè)操作,都要注冊(cè)一個(gè)與其對(duì)應(yīng)的確認(rèn)和補(bǔ)償(撤銷)操作。TCC 模型完全交由業(yè)務(wù)實(shí)現(xiàn),每個(gè)子業(yè)務(wù)都需要實(shí)現(xiàn) Try-Confirm-Cancel 三個(gè)接口,對(duì)業(yè)務(wù)侵入大,資源鎖定交由業(yè)務(wù)方。
- Try 階段:嘗試執(zhí)行,完成所有業(yè)務(wù)檢查(一致性), 預(yù)留必需業(yè)務(wù)資源(準(zhǔn)隔離性)。
- Confirm 階段:確認(rèn)執(zhí)行真正執(zhí)行業(yè)務(wù),不作任何業(yè)務(wù)檢查,只使用 Try 階段預(yù)留的業(yè)務(wù)資源,Confirm 操作滿足冪等性。要求具備冪等設(shè)計(jì),Confirm 失敗后需要進(jìn)行重試。
- Cancel 階段:取消執(zhí)行,釋放 Try 階段預(yù)留的業(yè)務(wù)資源 Cancel 操作滿足冪等性 Cancel 階段的異常和 Confirm 階段異常處理方案基本上一致。
一個(gè)完整的業(yè)務(wù)活動(dòng)由一個(gè)主業(yè)務(wù)服務(wù)與若干子業(yè)務(wù)服務(wù)組成:
比如一個(gè)轉(zhuǎn)賬操作:
基于 TCC 實(shí)現(xiàn)分布式事務(wù),會(huì)將原來(lái)只需要一個(gè)接口就可以實(shí)現(xiàn)的邏輯拆分為 Try、Confirm、Cancel 三個(gè)接口,所以代碼實(shí)現(xiàn)復(fù)雜度相對(duì)較高,需要在業(yè)務(wù)中寫(xiě)很多的補(bǔ)償機(jī)制代碼。
TCC將事務(wù)提交劃分成兩個(gè)階段,Try即為一階段,Confirm 和 Cancel 是二階段并行的兩個(gè)分支,二選一。從階段劃分上非常像2PC,我們是否可以說(shuō)TCC是一種2PC或者2PC變種呢?
對(duì)比一下 XA 事務(wù)模型,TCC 的兩階段提交與 XA 還是有一些區(qū)別:
本地消息表#
本地消息表最初是由eBay架構(gòu)師Dan Pritchett在一篇解釋 BASE 原理的論文《Base:An Acid Alternative》(https://queue.acm.org/detail.cfm?id=1394128)中提及的,業(yè)界目前使用這種方案是比較多的,其核心思想是將分布式事務(wù)拆分成本地事務(wù)進(jìn)行處理。
方案通過(guò)在事務(wù)主動(dòng)發(fā)起方額外新建事務(wù)消息表,事務(wù)發(fā)起方處理業(yè)務(wù)和記錄事務(wù)消息在本地事務(wù)中完成,輪詢事務(wù)消息表的數(shù)據(jù)發(fā)送事務(wù)消息,事務(wù)被動(dòng)方基于消息中間件消費(fèi)事務(wù)消息表中的事務(wù)。
基于本地消息表的方案,每個(gè)事務(wù)發(fā)起方都需要額外新建事務(wù)消息記錄表,用于記錄分布式事務(wù)的消息的發(fā)生、處理狀態(tài)。
事務(wù)發(fā)起方在處理完業(yè)務(wù)邏輯之后需要將當(dāng)前事務(wù)保存在消息表中,之后將消息發(fā)送到消息中間件中,并將消息的狀態(tài)設(shè)置為 “發(fā)送中”。
如果消息在投遞過(guò)程中丟失怎么辦呢?事務(wù)發(fā)起方可以設(shè)置一個(gè)定時(shí)任務(wù)主動(dòng)掃描狀態(tài)為 “發(fā)送中” 的消息重新投送。只有消息被業(yè)務(wù)方消費(fèi)完畢返回消費(fèi)成功的結(jié)果才確認(rèn)成功并將消息狀態(tài)改為“已發(fā)送”。
這里因?yàn)榫W(wǎng)絡(luò)異常或者發(fā)送異常導(dǎo)致一個(gè)消息可能會(huì)被重復(fù)發(fā)送,所以要求接收方要做到冪等性,允許重復(fù)消費(fèi)。
這種方案的好處就是方案簡(jiǎn)單,成本較低,實(shí)現(xiàn)也不復(fù)雜。
但是壞處也有很多,比如通過(guò)消息的方式延遲不好控制;本地消息表與業(yè)務(wù)耦合在一起沒(méi)有做到通用性;本地消息表基于數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn),有一定的瓶頸。
事務(wù)消息#
上面說(shuō)的本地消息表的模式無(wú)法支持本地事務(wù)執(zhí)行和消息發(fā)送一致性的問(wèn)題,如果能在本地事務(wù)執(zhí)行和發(fā)消息這兩個(gè)操作上加上事務(wù),那豈不是完美。
基于這個(gè)思路, 在 MQ 中存儲(chǔ)消息的狀態(tài)才是真理,消息生產(chǎn)者先把消息發(fā)送給MQ,此時(shí)消息狀態(tài)為“待確認(rèn)”,接著生產(chǎn)者去執(zhí)行本地事務(wù),如果執(zhí)行成功就給MQ發(fā)送消息讓他更改消息狀態(tài)為 “待發(fā)送”并發(fā)送消息,如果執(zhí)行失敗則刪除消息。
這樣就保證了本地事務(wù)和消息發(fā)送一致性問(wèn)題。
注意點(diǎn):由于MQ通常都會(huì)保證消息能夠投遞成功,因此,如果業(yè)務(wù)沒(méi)有及時(shí)返回ACK結(jié)果,那么就有可能造成MQ的重復(fù)消息投遞問(wèn)題。因此,對(duì)于消息最終一致性的方案,消息的消費(fèi)者必需要對(duì)消息的消費(fèi)支持冪等,不能造成同一條消息的重復(fù)消費(fèi)的情況。
SAGA 事務(wù)模型#
Saga是什么?Saga的定義是 “長(zhǎng)時(shí)間活動(dòng)的事務(wù) ”(Long Lived Transaction,后文簡(jiǎn)稱為L(zhǎng)LT)。他是普林斯頓大學(xué) HECTOR GARCIA-MOLINA 教授在1987年的一篇關(guān)于分布式數(shù)據(jù)庫(kù)的論文中提出來(lái)的概念。
Long Lived 從字面意義上不清晰,Long 到底意味著多長(zhǎng)?事務(wù)持續(xù)時(shí)間是一個(gè)小時(shí)、一天甚至一周嗎?其實(shí)都不是,時(shí)間跨度并不重要。重要的是什么?關(guān)鍵的是跨系統(tǒng)的多次“事務(wù)”,Saga 往往由多個(gè)外部的事務(wù)構(gòu)成,需要通過(guò)多次外部系統(tǒng)的消息交互,才能將整體事務(wù)從開(kāi)始遷移到結(jié)束狀態(tài),這和我們?cè)瓉?lái)常見(jiàn)的在一個(gè)數(shù)據(jù)庫(kù)的短事務(wù)不一樣。比如一個(gè)旅行的訂單,是由機(jī)票、旅館、租車三個(gè)子訂單構(gòu)成,都需要外部的確認(rèn),缺任何一個(gè)步驟,不能成行,這就是一個(gè)典型的 LLT。
看起來(lái) Sage 的定義與別的分布式事務(wù)沒(méi)有什么不同。分布式事務(wù)不就是多個(gè)不同的子事務(wù)構(gòu)成一個(gè)整體嗎?再來(lái)看看 補(bǔ)償機(jī)制:
每個(gè)本地事務(wù)有相應(yīng)的執(zhí)行模塊和補(bǔ)償模塊,當(dāng) Sage 事務(wù)中的任意一個(gè)本地事務(wù)出錯(cuò), 可以通過(guò)調(diào)用相關(guān)事務(wù)對(duì)應(yīng)的補(bǔ)償方法恢復(fù),達(dá)到事務(wù)的最終一致性。
Saga 模型是把一個(gè)分布式事務(wù)拆分為多個(gè)本地事務(wù),每個(gè)本地事務(wù)都有相應(yīng)的執(zhí)行模塊和補(bǔ)償模塊(對(duì)應(yīng)TCC 中的 Confirm 和 Cancel),當(dāng) Saga 事務(wù)中任意一個(gè)本地事務(wù)出錯(cuò)時(shí),可以通過(guò)調(diào)用相關(guān)的補(bǔ)償方法恢復(fù)之前的事務(wù),達(dá)到事務(wù)最終一致性。
由于 Saga 模型中沒(méi)有 Prepare 階段,因此事務(wù)間不能保證隔離性,當(dāng)多個(gè) Saga 事務(wù)操作同一資源時(shí),就會(huì)產(chǎn)生更新丟失、臟數(shù)據(jù)讀取等問(wèn)題,這時(shí)需要在業(yè)務(wù)層控制并發(fā),例如:
- 在應(yīng)用層面加鎖;
- 應(yīng)用層面預(yù)先凍結(jié)資源。
Saga 恢復(fù)方式
Saga 支持向前和向后恢復(fù):
- 向后恢復(fù):補(bǔ)償所有已完成的事務(wù),如果任一的事務(wù)失敗;
- 向前恢復(fù):重試失敗的事務(wù),假設(shè)每個(gè)子事務(wù)最終都會(huì)成功。
雖然 Saga 和 TCC 都是補(bǔ)償事務(wù),但是由于提交階段不同,所以兩者也是有不同的:
- Saga 沒(méi)有 Try 行為直接 Commit,所以會(huì)留下原始事務(wù)操作的痕跡,Cancel 屬于不完美補(bǔ)償,需要考慮對(duì)業(yè)務(wù)上的影響。TCC Cancel 是完美補(bǔ)償?shù)?Rollback,補(bǔ)償操作會(huì)徹底清理之前的原始事務(wù)操作,用戶是感知不到事務(wù)取消之前的狀態(tài)信息的。
- Saga 的補(bǔ)償操作通常可以異步執(zhí)行,TCC 的 Cancel 和 Confirm 可以跟進(jìn)需要是否異步化。
- Saga 對(duì)業(yè)務(wù)侵入較小,只需要提供一個(gè)逆向操作的 Cancel 即可;而 TCC 需要對(duì)業(yè)務(wù)進(jìn)行全局性的流程改造。
- TCC 最少通信次數(shù)為 2n,而 Saga 為 n(n=子事務(wù)的數(shù)量)。
因?yàn)橐彩遣捎醚a(bǔ)償機(jī)制,那么必然要求服務(wù)保持冪等性,如果服務(wù)調(diào)用超時(shí)需要通過(guò)冪等性來(lái)避免多次請(qǐng)求帶來(lái)的問(wèn)題。
事務(wù)特性的滿足:
原子性:Saga 協(xié)調(diào)器保證整體事務(wù)要么全部執(zhí)行成功,要么全部回滾。
一致性:Sage 保證最終一致性。
持久性:Saga 將整體事務(wù)拆分成獨(dú)立的本地事務(wù),所以持久性在本地事務(wù)中很好實(shí)現(xiàn)。
但是隔離性 Saga 無(wú)法實(shí)現(xiàn),因?yàn)榇笫聞?wù)被拆分為多個(gè)小事務(wù),每個(gè)事務(wù)提交的時(shí)機(jī)不同很難保證已提交的小事務(wù)不被別人可見(jiàn)。
目前業(yè)界提供兩類 Saga 的實(shí)現(xiàn)方式:
- 一種是集中式協(xié)調(diào)的實(shí)現(xiàn)方式。集中式協(xié)調(diào)方式就是通過(guò)一個(gè) Saga 對(duì)象來(lái)追蹤所有的 Saga 子任務(wù)的調(diào)用,由它來(lái)管理,追蹤整個(gè)事務(wù)是否應(yīng)該提交或補(bǔ)償。這種方式帶來(lái)的缺點(diǎn)就是這種協(xié)調(diào)方式必然要與第一個(gè)Saga 事務(wù)耦合,即與業(yè)務(wù)耦合在一起。
- 一種是分布式實(shí)現(xiàn)方式。分布式協(xié)調(diào)方式肯定就能避免耦合的問(wèn)題。分布式實(shí)現(xiàn)的方案也很多,比如通過(guò)事件機(jī)制來(lái)實(shí)現(xiàn),一條 Saga 事務(wù)鏈上的所有事務(wù)都訂閱同一個(gè)事件,如果失敗則通過(guò)失敗對(duì)應(yīng)的事件消息來(lái)回滾即可。這種方式帶來(lái)的好處肯定是顯而易見(jiàn)的,但是也會(huì)有另一個(gè)問(wèn)題,多個(gè)事件帶來(lái)的肯定是高并發(fā)的處理,那么會(huì)不會(huì)因?yàn)槎鄠€(gè)事件處理相關(guān)的問(wèn)題帶來(lái)一些循環(huán)依賴的問(wèn)題。
開(kāi)源分布式事務(wù)框架簡(jiǎn)介#
Seata
Seata(Simple Extensible Autonomous Transaction Architecture,簡(jiǎn)單可擴(kuò)展自治事務(wù)框架)是 2019 年 1 月份螞蟻金服和阿里巴巴共同開(kāi)源的分布式事務(wù)解決方案。
Seata 會(huì)有 4 種分布式事務(wù)解決方案,分別是 AT 模式、TCC 模式、Saga 模式和 XA 模式。
XA 模式
XA 模式是 Seata 將會(huì)開(kāi)源的另一種無(wú)侵入的分布式事務(wù)解決方案,任何實(shí)現(xiàn)了 XA 協(xié)議的數(shù)據(jù)庫(kù)都可以作為資源參與到分布式事務(wù)中,目前主流數(shù)據(jù)庫(kù),例如 MySql、Oracle、DB2、Oceanbase 等均支持 XA 協(xié)議。
XA 協(xié)議有一系列的指令,分別對(duì)應(yīng)一階段和二階段操作。“xa start” 和 “xa end” 用于開(kāi)啟和結(jié)束XA 事務(wù);“xa prepare” 用于預(yù)提交 XA 事務(wù),對(duì)應(yīng)一階段準(zhǔn)備;“xa commit”和“xa rollback”用于提交、回滾 XA 事務(wù),對(duì)應(yīng)二階段提交和回滾。
在 XA 模式下,每一個(gè) XA 事務(wù)都是一個(gè)事務(wù)參與者。分布式事務(wù)開(kāi)啟之后,首先在一階段執(zhí)行“xa start”、“業(yè)務(wù) SQL”、“xa end”和 “xa prepare” 完成 XA 事務(wù)的執(zhí)行和預(yù)提交;二階段如果提交的話就執(zhí)行 “xa commit”,如果是回滾則執(zhí)行“xa rollback”。這樣便能保證所有 XA 事務(wù)都提交或者都回滾。
XA 模式下,用戶只需關(guān)注自己的“業(yè)務(wù) SQL”,Seata 框架會(huì)自動(dòng)生成一階段、二階段操作;XA 模式的實(shí)現(xiàn)如下:
- 一階段:
在 XA 模式的一階段,Seata 會(huì)攔截“業(yè)務(wù) SQL”,在“業(yè)務(wù) SQL”之前開(kāi)啟 XA 事務(wù)(“xa start”),然后執(zhí)行“業(yè)務(wù) SQL”,結(jié)束 XA 事務(wù)“xa end”,最后預(yù)提交 XA 事務(wù)(“xa prepare”),這樣便完成 “業(yè)務(wù) SQL”的準(zhǔn)備操作。
- 二階段提交:
執(zhí)行“xa commit”指令,提交 XA 事務(wù),此時(shí)“業(yè)務(wù) SQL”才算真正的提交至數(shù)據(jù)庫(kù)。
- 二階段回滾:
執(zhí)行“xa rollback”指令,回滾 XA 事務(wù),完成“業(yè)務(wù) SQL”回滾,釋放數(shù)據(jù)庫(kù)鎖資源。
XA 模式下,用戶只需關(guān)注“業(yè)務(wù) SQL”,Seata 會(huì)自動(dòng)生成一階段、二階段提交和二階段回滾操作。XA 模式和 AT 模式一樣是一種對(duì)業(yè)務(wù)無(wú)侵入性的解決方案;但與 AT 模式不同的是,XA 模式將快照數(shù)據(jù)和行鎖等通過(guò) XA 指令委托給了數(shù)據(jù)庫(kù)來(lái)完成,這樣 XA 模式實(shí)現(xiàn)更加輕量化。
AT 模式
AT 模式是一種無(wú)侵入的分布式事務(wù)解決方案。在 AT 模式下,用戶只需關(guān)注自己的“業(yè)務(wù) SQL”,用戶的 “業(yè)務(wù) SQL” 作為一階段,Seata 框架會(huì)自動(dòng)生成事務(wù)的二階段提交和回滾操作。
AT 模式的一階段、二階段提交和回滾
均由 Seata 框架自動(dòng)生成,用戶只需編寫(xiě)“業(yè)務(wù) SQL”,便能輕松接入分布式事務(wù),AT 模式是一種對(duì)業(yè)務(wù)無(wú)任何侵入的分布式事務(wù)解決方案。
TCC 模式
2019 年 3 月份,Seata 開(kāi)源了 TCC 模式,該模式由螞蟻金服貢獻(xiàn)。TCC 模式需要用戶根據(jù)自己的業(yè)務(wù)場(chǎng)景實(shí)現(xiàn) Try、Confirm 和 Cancel 三個(gè)操作;事務(wù)發(fā)起方在一階段 執(zhí)行 Try 方式,在二階段提交執(zhí)行 Confirm 方法,二階段回滾執(zhí)行 Cancel 方法。
TCC 三個(gè)方法描述:
- Try:資源的檢測(cè)和預(yù)留;
- Confirm:執(zhí)行的業(yè)務(wù)操作提交;要求 Try 成功 Confirm 一定要能成功;
- Cancel:預(yù)留資源釋放。
用戶接入 TCC 模式,最重要的事情就是考慮如何將業(yè)務(wù)模型拆成 2 階段,實(shí)現(xiàn)成 TCC 的 3 個(gè)方法,并且保證 Try 成功 Confirm 一定能成功。相對(duì)于 AT 模式,TCC 模式對(duì)業(yè)務(wù)代碼有一定的侵入性,但是 TCC 模式無(wú) AT 模式的全局行鎖,TCC 性能會(huì)比 AT 模式高很多。
Saga 模式
Saga 模式是 Seata 即將開(kāi)源的長(zhǎng)事務(wù)解決方案,將由螞蟻金服主要貢獻(xiàn)。在 Saga 模式下,分布式事務(wù)內(nèi)有多個(gè)參與者,每一個(gè)參與者都是一個(gè)沖正補(bǔ)償服務(wù),需要用戶根據(jù)業(yè)務(wù)場(chǎng)景實(shí)現(xiàn)其正向操作和逆向回滾操作。
分布式事務(wù)執(zhí)行過(guò)程中,依次執(zhí)行各參與者的正向操作,如果所有正向操作均執(zhí)行成功,那么分布式事務(wù)提交。如果任何一個(gè)正向操作執(zhí)行失敗,那么分布式事務(wù)會(huì)去退回去執(zhí)行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務(wù)回到初始狀態(tài)。
Saga 模式下分布式事務(wù)通常是由事件驅(qū)動(dòng)的,各個(gè)參與者之間是異步執(zhí)行的,Saga 模式是一種長(zhǎng)事務(wù)解決方案。
ServiceComb
ServiceComb 是華為開(kāi)源的微服務(wù)框架,目前已升級(jí)為 Apache 頂級(jí)項(xiàng)目。 準(zhǔn)確來(lái)說(shuō)它并不是一個(gè)純粹的分布式事務(wù)框架而是微服務(wù)框架,最開(kāi)始的版本是 Go 語(yǔ)言,后面支持了 Java。
ServiceComb 由 3 個(gè)子項(xiàng)目組成:
- java-chassis:服務(wù)治理
- service-center:服務(wù)注冊(cè)
- saga:分布式事務(wù)解決
從名字上看很顯然是基于 Saga 模式開(kāi)發(fā)的柔性事務(wù)方案。Saga系統(tǒng)分為兩部分:Alpha 和 Omega。Alpha 是獨(dú)立的服務(wù),扮演事務(wù)協(xié)調(diào)器的作用。Omega 作為開(kāi)發(fā)組件,和業(yè)務(wù)進(jìn)程運(yùn)行在一起。
Omega 會(huì)以切面編程的方式向應(yīng)用程序注入相關(guān)的處理模塊。這里有攔截請(qǐng)求的模塊, 用來(lái)幫助我們構(gòu)建分布式事務(wù)調(diào)用的上下文。 同時(shí)在事務(wù)處理初始階段處理事務(wù)的相關(guān)準(zhǔn)備的操作,例如創(chuàng)建 Saga 起始事件,以及相關(guān)的的起始事件, 根據(jù)事務(wù)的執(zhí)行的成功或者失敗生產(chǎn)相關(guān)的事務(wù)終止或者失敗事件。
Omega 會(huì)與 Alpha 進(jìn)行鏈接會(huì)把這些事件通知給 Alpha。 Alpha 可以在后臺(tái)進(jìn)行分析,根據(jù) Saga 事務(wù)執(zhí)行的情況給 Omega 下達(dá)相關(guān)的指令進(jìn)行相關(guān)的回滾恢復(fù)。
這樣設(shè)計(jì)的好處是 Saga 實(shí)現(xiàn)代碼與用戶的代碼分離, 用戶只需要添加幾個(gè) annotation,Saga 實(shí)現(xiàn)就能 Saga 事件的執(zhí)行情況并進(jìn)行相關(guān)的處理。
作者: rickiyang
原文鏈接:https://www.cnblogs.com/rickiyang/p/13704868.html
如果感覺(jué)本文對(duì)你有幫助,幫忙關(guān)注轉(zhuǎn)發(fā)支持一下
總結(jié)
以上是生活随笔為你收集整理的oledb 访问接口sqlncli10返回了消息 没有活动事务_这样理解分布式事务你是不是就会懂了?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c 结构体在声明时赋值_Java基础知识
- 下一篇: filezilla 设置filezill