一篇文章帶你學(xué)習(xí)分布式事務(wù)

Java小鋪IP屬地: 湖南
0.921字?jǐn)?shù) 6,292

一. 事務(wù)

1.1 什么是事務(wù)

數(shù)據(jù)庫(kù)事務(wù)(簡(jiǎn)稱(chēng):事務(wù),Transaction)是指數(shù)據(jù)庫(kù)執(zhí)行過(guò)程中的一個(gè)邏輯單位,由一個(gè)有限的數(shù)據(jù)庫(kù)操作序列構(gòu)成。

事務(wù)擁有以下四個(gè)特性,習(xí)慣上被稱(chēng)為ACID特性:

原子性(Atomicity):事務(wù)作為一個(gè)整體被執(zhí)行,包含在其中的對(duì)數(shù)據(jù)庫(kù)的操作要么全部被執(zhí)行,要么都不執(zhí)行。

一致性(Consistency):事務(wù)應(yīng)確保數(shù)據(jù)庫(kù)的狀態(tài)從一個(gè)一致?tīng)顟B(tài)轉(zhuǎn)變?yōu)榱硪粋€(gè)一致?tīng)顟B(tài)。一致?tīng)顟B(tài)是指數(shù)據(jù)庫(kù)中的數(shù)據(jù)應(yīng)滿(mǎn)足完整性約束。除此之外,一致性還有另外一層語(yǔ)義,就是事務(wù)的中間狀態(tài)不能被觀察到(這層語(yǔ)義也有說(shuō)應(yīng)該屬于原子性)。

隔離性(Isolation):多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),一個(gè)事務(wù)的執(zhí)行不應(yīng)影響其他事務(wù)的執(zhí)行,如同只有這一個(gè)操作在被數(shù)據(jù)庫(kù)所執(zhí)行一樣。

持久性(Durability):已被提交的事務(wù)對(duì)數(shù)據(jù)庫(kù)的修改應(yīng)該永久保存在數(shù)據(jù)庫(kù)中。在事務(wù)結(jié)束時(shí),此操作將不可逆轉(zhuǎn)。

1.2 本地事務(wù)

起初,事務(wù)僅限于對(duì)單一數(shù)據(jù)庫(kù)資源的訪問(wèn)控制:

架構(gòu)服務(wù)化以后,事務(wù)的概念延伸到了服務(wù)中。倘若將一個(gè)單一的服務(wù)操作作為一個(gè)事務(wù),那么整個(gè)服務(wù)操作只能涉及一個(gè)單一的數(shù)據(jù)庫(kù)資源:

這類(lèi)基于單個(gè)服務(wù)單一數(shù)據(jù)庫(kù)資源訪問(wèn)的事務(wù),被稱(chēng)為本地事務(wù)(Local Transaction)。

二. 分布式事務(wù)應(yīng)用架構(gòu)

本地事務(wù)主要限制在單個(gè)會(huì)話(huà)內(nèi),不涉及多個(gè)數(shù)據(jù)庫(kù)資源。但是在基于SOA(Service-Oriented Architecture,面向服務(wù)架構(gòu))的分布式應(yīng)用環(huán)境下,越來(lái)越多的應(yīng)用要求對(duì)多個(gè)數(shù)據(jù)庫(kù)資源,多個(gè)服務(wù)的訪問(wèn)都能納入到同一個(gè)事務(wù)當(dāng)中,分布式事務(wù)應(yīng)運(yùn)而生。

最早的分布式事務(wù)應(yīng)用架構(gòu)很簡(jiǎn)單,不涉及服務(wù)間的訪問(wèn)調(diào)用,僅僅是服務(wù)內(nèi)操作涉及到對(duì)多個(gè)數(shù)據(jù)庫(kù)資源的訪問(wèn)。

當(dāng)一個(gè)服務(wù)操作訪問(wèn)不同的數(shù)據(jù)庫(kù)資源,又希望對(duì)它們的訪問(wèn)具有事務(wù)特性時(shí),就需要采用分布式事務(wù)來(lái)協(xié)調(diào)所有的事務(wù)參與者。

對(duì)于上面介紹的分布式事務(wù)應(yīng)用架構(gòu),盡管一個(gè)服務(wù)操作會(huì)訪問(wèn)多個(gè)數(shù)據(jù)庫(kù)資源,但是畢竟整個(gè)事務(wù)還是控制在單一服務(wù)的內(nèi)部。如果一個(gè)服務(wù)操作需要調(diào)用另外一個(gè)服務(wù),這時(shí)的事務(wù)就需要跨越多個(gè)服務(wù)了。在這種情況下,起始于某個(gè)服務(wù)的事務(wù)在調(diào)用另外一個(gè)服務(wù)的時(shí)候,需要以某種機(jī)制流轉(zhuǎn)到另外一個(gè)服務(wù),從而使被調(diào)用的服務(wù)訪問(wèn)的資源也自動(dòng)加入到該事務(wù)當(dāng)中來(lái)。下圖反映了這樣一個(gè)跨越多個(gè)服務(wù)的分布式事務(wù):

如果將上面這兩種場(chǎng)景(一個(gè)服務(wù)可以調(diào)用多個(gè)數(shù)據(jù)庫(kù)資源,也可以調(diào)用其他服務(wù))結(jié)合在一起,對(duì)此進(jìn)行延伸,整個(gè)分布式事務(wù)的參與者將會(huì)組成如下圖所示的樹(shù)形拓?fù)浣Y(jié)構(gòu)。在一個(gè)跨服務(wù)的分布式事務(wù)中,事務(wù)的發(fā)起者和提交均系同一個(gè),它可以是整個(gè)調(diào)用的客戶(hù)端,也可以是客戶(hù)端最先調(diào)用的那個(gè)服務(wù)。

較之基于單一數(shù)據(jù)庫(kù)資源訪問(wèn)的本地事務(wù),分布式事務(wù)的應(yīng)用架構(gòu)更為復(fù)雜。在不同的分布式應(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 特性。因此,想要了解一個(gè)分布式事務(wù),就先從了解它是怎么實(shí)現(xiàn)事務(wù) ACID 特性開(kāi)始。

下文將從兩個(gè)最常見(jiàn)的分布式事務(wù)模型入手,著重分析分布式事務(wù)的基礎(chǔ)共通點(diǎn),即如何保證分布式事務(wù)的 ACID 特性。

三. 常見(jiàn)分布式事務(wù)模型 ACID 實(shí)現(xiàn)分析

3.1 X/Open XA 協(xié)議

最早的分布式事務(wù)模型是 X/Open 國(guó)際聯(lián)盟提出的 X/Open Distributed Transaction Processing(DTP)模型,也就是大家常說(shuō)的 X/Open XA 協(xié)議,簡(jiǎn)稱(chēng)XA 協(xié)議。

DTP 模型中包含一個(gè)全局事務(wù)管理器(TM,Transaction Manager)和多個(gè)資源管理器(RM,Resource Manager)。全局事務(wù)管理器負(fù)責(zé)管理全局事務(wù)狀態(tài)與參與的資源,協(xié)同資源一起提交或回滾;資源管理器則負(fù)責(zé)具體的資源操作。

XA 協(xié)議描述了 TM 與 RM 之間的接口,允許多個(gè)資源在同一分布式事務(wù)中訪問(wèn)。

基于 DTP 模型的分布式事務(wù)流程大致如下:

應(yīng)用程序(AP,Application)向 TM 申請(qǐng)開(kāi)始一個(gè)全局事務(wù)。

針對(duì)要操作的 RM,AP 會(huì)先向 TM 注冊(cè)(TM 負(fù)責(zé)記錄 AP 操作過(guò)哪些 RM,即分支事務(wù)),TM 通過(guò) XA 接口函數(shù)通知相應(yīng) RM 開(kāi)啟分布式事務(wù)的子事務(wù),接著 AP 就可以對(duì)該 RM 管理的資源進(jìn)行操作。

當(dāng) AP 對(duì)所有 RM 操作完畢后,AP 根據(jù)執(zhí)行情況通知 TM 提交或回滾該全局事務(wù),TM 通過(guò) XA 接口函數(shù)通知各 RM 完成操作。TM 會(huì)先要求各個(gè) RM 做預(yù)提交,所有 RM 返回成功后,再要求各 RM 做正式提交,XA 協(xié)議要求,一旦 RM 預(yù)提交成功,則后續(xù)的正式提交也必須能成功;如果任意一個(gè) RM 預(yù)提交失敗,則 TM 通知各 RM 回滾。

所有 RM 提交或回滾完成后,全局事務(wù)結(jié)束。

3.1.1 原子性

XA 協(xié)議使用 2PC(Two Phase Commit,兩階段提交)原子提交協(xié)議來(lái)保證分布式事務(wù)原子性。

兩階段提交是指將提交過(guò)程分為兩個(gè)階段,即準(zhǔn)備階段(投票階段)和提交階段(執(zhí)行階段):

準(zhǔn)備階段:

TM 向每個(gè) RM 發(fā)送準(zhǔn)備消息。如果 RM 的本地事務(wù)操作執(zhí)行成功,則返回成功;如果 RM 的本地事務(wù)操作執(zhí)行失敗,則返回失敗。

提交階段

如果 TM 收到了所有 RM 回復(fù)的成功消息,則向每個(gè) RM 發(fā)送提交消息;否則發(fā)送回滾消息;RM 根據(jù) TM 的指令執(zhí)行提交或者回滾本地事務(wù)操作,釋放所有事務(wù)處理過(guò)程中使用的鎖資源。

3.1.2 隔離性

XA 協(xié)議中沒(méi)有描述如何實(shí)現(xiàn)分布式事務(wù)的隔離性,但是 XA 協(xié)議要求DTP 模型中的每個(gè) RM 都要實(shí)現(xiàn)本地事務(wù),也就是說(shuō),基于 XA 協(xié)議實(shí)現(xiàn)的分布式事務(wù)的隔離性是由每個(gè) RM 本地事務(wù)的隔離性來(lái)保證的,當(dāng)一個(gè)分布式事務(wù)的所有子事務(wù)都是隔離的,那么這個(gè)分布式事務(wù)天然的就實(shí)現(xiàn)了隔離性。

以 MySQL 來(lái)舉例,MySQL 使用 2PL(Two-Phase Locking,兩階段鎖)機(jī)制來(lái)控制本地事務(wù)的并發(fā),保證隔離性。2PL 與 2PC 類(lèi)似,也是將鎖操作分為加鎖和解鎖兩個(gè)階段,并且保證兩個(gè)階段完全不相交。加鎖階段,只加鎖,不放鎖。解鎖階段,只放鎖,不加鎖。

如上圖所示,在一個(gè)本地事務(wù)中,每執(zhí)行一條更新操作之前,都會(huì)先獲取對(duì)應(yīng)的鎖資源,只有獲取鎖資源成功才會(huì)執(zhí)行該操作,并且一旦獲取了鎖資源就會(huì)持有該鎖資源直到本事務(wù)執(zhí)行結(jié)束。

MySQL 通過(guò)這種 2PL 機(jī)制,可以保證在本地事務(wù)執(zhí)行過(guò)程中,其他并發(fā)事務(wù)不能操作相同資源,從而實(shí)現(xiàn)了事務(wù)隔離。

3.1.3 一致性

前面提到一致性有兩層語(yǔ)義,一層是確保事務(wù)執(zhí)行結(jié)束后,數(shù)據(jù)庫(kù)從一個(gè)一致?tīng)顟B(tài)轉(zhuǎn)變?yōu)榱硪粋€(gè)一致?tīng)顟B(tài)。另一層語(yǔ)義是事務(wù)執(zhí)行過(guò)程中的中間狀態(tài)不能被觀察到。

前一層語(yǔ)義的實(shí)現(xiàn)很簡(jiǎn)單,通過(guò)原子性、隔離性以及 RM 自身一致性的實(shí)現(xiàn)就可以保證。至于后一層語(yǔ)義,我們先來(lái)看看單個(gè) RM 上的本地事務(wù)是怎么實(shí)現(xiàn)的。還是以 MySQL 舉例,MySQL 通過(guò) MVCC(Multi Version Concurrency Control,多版本并發(fā)控制)機(jī)制,為每個(gè)一致性狀態(tài)生成快照(Snapshot),每個(gè)事務(wù)看到的都是各Snapshot對(duì)應(yīng)的一致性狀態(tài),從而也就保證了本地事務(wù)的中間狀態(tài)不會(huì)被觀察到。

雖然單個(gè) RM 上實(shí)現(xiàn)了Snapshot,但是在分布式應(yīng)用架構(gòu)下,會(huì)遇到什么問(wèn)題呢?

如上圖所示,在 RM1 的本地子事務(wù)提交完畢到 RM2 的本地子事務(wù)提交完畢之間,只能讀到 RM1 上子事務(wù)執(zhí)行的內(nèi)容,讀不到 RM2 上的子事務(wù)。也就是說(shuō),雖然在單個(gè) RM 上的本地事務(wù)是一致的,但是從全局來(lái)看,一個(gè)全局事務(wù)執(zhí)行過(guò)程的中間狀態(tài)被觀察到了,全局一致性就被破壞了。

XA 協(xié)議并沒(méi)有定義怎么實(shí)現(xiàn)全局的 Snapshot,像 MySQL 官方文檔里就建議使用串行化的隔離級(jí)別來(lái)保證分布式事務(wù)一致性: “As with nondistributed transactions, SERIALIZABLE may be preferred if your applications are sensitive to read phenomena. REPEATABLE READ may not be sufficient for distributed transactions.”(對(duì)于分布式事務(wù)來(lái)說(shuō),可重復(fù)讀隔離級(jí)別不足以保證事務(wù)一致性,如果你的程序有全局一致性讀要求,可以考慮串行化隔離級(jí)別.)

當(dāng)然,由于串行化隔離級(jí)別的性能較差,所以很多分布式數(shù)據(jù)庫(kù)都自己實(shí)現(xiàn)了分布式 MVCC 機(jī)制來(lái)提供全局的一致性讀。一個(gè)基本思路是用一個(gè)集中式或者邏輯上單調(diào)遞增的東西來(lái)控制生成全局 Snapshot,每個(gè)事務(wù)或者每條 SQL 執(zhí)行時(shí)都去獲取一次,從而實(shí)現(xiàn)不同隔離級(jí)別下的一致性。比如 Google 的 Spanner 就是用 TrueTime 來(lái)控制訪問(wèn)全局 Snapshot。在這里順便給大家推薦一個(gè)架構(gòu)交流群:617434785,里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識(shí)體系。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源。相信對(duì)于已經(jīng)工作和遇到技術(shù)瓶頸的碼友,在這個(gè)群里會(huì)有你需要的內(nèi)容。

3.1.4 小結(jié)

XA 協(xié)議通常實(shí)現(xiàn)在數(shù)據(jù)庫(kù)資源層,直接作用于資源管理器上。因此,基于 XA 協(xié)議實(shí)現(xiàn)的分布式事務(wù)產(chǎn)品,無(wú)論是分布式數(shù)據(jù)庫(kù),還是分布式事務(wù)框架,對(duì)業(yè)務(wù)幾乎都沒(méi)有侵入,就像使用普通數(shù)據(jù)庫(kù)一樣。

XA 協(xié)議嚴(yán)格保障事務(wù) ACID 特性,能夠滿(mǎn)足所有業(yè)務(wù)領(lǐng)域的功能需求,但是,這同樣是一把雙刃劍。

由于隔離性的互斥要求,在事務(wù)執(zhí)行過(guò)程中,所有的資源都被鎖定,只適用于執(zhí)行時(shí)間確定的短事務(wù)。同時(shí),整個(gè)事務(wù)期間都是獨(dú)占數(shù)據(jù),對(duì)于熱點(diǎn)數(shù)據(jù)的并發(fā)性能可能會(huì)很低,實(shí)現(xiàn)了分布式 MVCC 或樂(lè)觀鎖(optimistic locking)以后,性能可能會(huì)有所提升。

同時(shí),為了保障一致性,要求所有 RM 同等可信、可靠,要求故障恢復(fù)機(jī)制可靠、快速,在網(wǎng)絡(luò)故障隔離的情況下,服務(wù)基本不可用。

3.2 TCC 模型

TCC(Try-Confirm-Cancel)分布式事務(wù)模型相對(duì)于 XA 等傳統(tǒng)模型,其特征在于它不依賴(lài)資源管理器(RM)對(duì)分布式事務(wù)的支持,而是通過(guò)對(duì)業(yè)務(wù)邏輯的分解來(lái)實(shí)現(xiàn)分布式事務(wù)。

TCC 模型認(rèn)為對(duì)于業(yè)務(wù)系統(tǒng)中一個(gè)特定的業(yè)務(wù)邏輯,其對(duì)外提供服務(wù)時(shí),必須接受一些不確定性,即對(duì)業(yè)務(wù)邏輯初步操作的調(diào)用僅是一個(gè)臨時(shí)性操作,調(diào)用它的主業(yè)務(wù)服務(wù)保留了后續(xù)的取消權(quán)。如果主業(yè)務(wù)服務(wù)認(rèn)為全局事務(wù)應(yīng)該回滾,它會(huì)要求取消之前的臨時(shí)性操作,這就對(duì)應(yīng)從業(yè)務(wù)服務(wù)的取消操作。而當(dāng)主業(yè)務(wù)服務(wù)認(rèn)為全局事務(wù)應(yīng)該提交時(shí),它會(huì)放棄之前臨時(shí)性操作的取消權(quán),這對(duì)應(yīng)從業(yè)務(wù)服務(wù)的確認(rèn)操作。每一個(gè)初步操作,最終都會(huì)被確認(rèn)或取消。

因此,針對(duì)一個(gè)具體的業(yè)務(wù)服務(wù),TCC 分布式事務(wù)模型需要業(yè)務(wù)系統(tǒng)提供三段業(yè)務(wù)邏輯:

初步操作 Try:完成所有業(yè)務(wù)檢查,預(yù)留必須的業(yè)務(wù)資源。

確認(rèn)操作 Confirm:真正執(zhí)行的業(yè)務(wù)邏輯,不作任何業(yè)務(wù)檢查,只使用 Try 階段預(yù)留的業(yè)務(wù)資源。因此,只要 Try 操作成功,Confirm 必須能成功。另外,Confirm 操作需滿(mǎn)足冪等性,保證一筆分布式事務(wù)有且只能成功一次。

取消操作 Cancel:釋放 Try 階段預(yù)留的業(yè)務(wù)資源。同樣的,Cancel 操作也需要滿(mǎn)足冪等性。

TCC 分布式事務(wù)模型包括三部分:

主業(yè)務(wù)服務(wù):主業(yè)務(wù)服務(wù)為整個(gè)業(yè)務(wù)活動(dòng)的發(fā)起方,服務(wù)的編排者,負(fù)責(zé)發(fā)起并完成整個(gè)業(yè)務(wù)活動(dòng)。

從業(yè)務(wù)服務(wù):從業(yè)務(wù)服務(wù)是整個(gè)業(yè)務(wù)活動(dòng)的參與方,負(fù)責(zé)提供 TCC 業(yè)務(wù)操作,實(shí)現(xiàn)初步操作(Try)、確認(rèn)操作(Confirm)、取消操作(Cancel)三個(gè)接口,供主業(yè)務(wù)服務(wù)調(diào)用。

業(yè)務(wù)活動(dòng)管理器:業(yè)務(wù)活動(dòng)管理器管理控制整個(gè)業(yè)務(wù)活動(dòng),包括記錄維護(hù) TCC 全局事務(wù)的事務(wù)狀態(tài)和每個(gè)從業(yè)務(wù)服務(wù)的子事務(wù)狀態(tài),并在業(yè)務(wù)活動(dòng)提交時(shí)調(diào)用所有從業(yè)務(wù)服務(wù)的 Confirm 操作,在業(yè)務(wù)活動(dòng)取消時(shí)調(diào)用所有從業(yè)務(wù)服務(wù)的 Cancel 操作。

一個(gè)完整的 TCC 分布式事務(wù)流程如下:

主業(yè)務(wù)服務(wù)首先開(kāi)啟本地事務(wù);

主業(yè)務(wù)服務(wù)向業(yè)務(wù)活動(dòng)管理器申請(qǐng)啟動(dòng)分布式事務(wù)主業(yè)務(wù)活動(dòng);

然后針對(duì)要調(diào)用的從業(yè)務(wù)服務(wù),主業(yè)務(wù)活動(dòng)先向業(yè)務(wù)活動(dòng)管理器注冊(cè)從業(yè)務(wù)活動(dòng),然后調(diào)用從業(yè)務(wù)服務(wù)的 Try 接口;

當(dāng)所有從業(yè)務(wù)服務(wù)的 Try 接口調(diào)用成功,主業(yè)務(wù)服務(wù)提交本地事務(wù);若調(diào)用失敗,主業(yè)務(wù)服務(wù)回滾本地事務(wù);

若主業(yè)務(wù)服務(wù)提交本地事務(wù),則 TCC 模型分別調(diào)用所有從業(yè)務(wù)服務(wù)的 Confirm 接口;若主業(yè)務(wù)服務(wù)回滾本地事務(wù),則分別調(diào)用 Cancel 接口;

所有從業(yè)務(wù)服務(wù)的 Confirm 或 Cancel 操作完成后,全局事務(wù)結(jié)束。

3.2.1 原子性

TCC 模型也使用 2PC 原子提交協(xié)議來(lái)保證事務(wù)原子性。Try 操作對(duì)應(yīng)2PC 的一階段準(zhǔn)備(Prepare);Confirm 對(duì)應(yīng) 2PC 的二階段提交(Commit),Cancel 對(duì)應(yīng) 2PC 的二階段回滾(Rollback),可以說(shuō) TCC 就是應(yīng)用層的 2PC。

3.2.2 隔離性

TCC 分布式事務(wù)模型僅提供兩階段原子提交協(xié)議,保證分布式事務(wù)原子性。事務(wù)的隔離交給業(yè)務(wù)邏輯來(lái)實(shí)現(xiàn)。

隔離的本質(zhì)是控制并發(fā),防止并發(fā)事務(wù)操作相同資源而引起的結(jié)果錯(cuò)亂。

舉個(gè)例子,比如金融行業(yè)里管理用戶(hù)資金,當(dāng)用戶(hù)發(fā)起交易時(shí),一般會(huì)先檢查用戶(hù)資金,如果資金充足,則扣除相應(yīng)交易金額,增加賣(mài)家資金,完成交易。如果沒(méi)有事務(wù)隔離,用戶(hù)同時(shí)發(fā)起兩筆交易,兩筆交易的檢查都認(rèn)為資金充足,實(shí)際上卻只夠支付一筆交易,結(jié)果兩筆交易都支付成功,導(dǎo)致資損。

可以發(fā)現(xiàn),并發(fā)控制是業(yè)務(wù)邏輯執(zhí)行正確的保證,但是像兩階段鎖這樣的并發(fā)訪問(wèn)控制技術(shù)要求一直持有數(shù)據(jù)庫(kù)資源鎖直到整個(gè)事務(wù)執(zhí)行結(jié)束,特別是在分布式事務(wù)架構(gòu)下,要求持有鎖到分布式事務(wù)第二階段執(zhí)行結(jié)束,也就是說(shuō),分布式事務(wù)會(huì)加長(zhǎng)資源鎖的持有時(shí)間,導(dǎo)致并發(fā)性能進(jìn)一步下降。

因此,TCC 模型的隔離性思想就是通過(guò)業(yè)務(wù)的改造,在第一階段結(jié)束之后,從底層數(shù)據(jù)庫(kù)資源層面的加鎖過(guò)渡為上層業(yè)務(wù)層面的加鎖,從而釋放底層數(shù)據(jù)庫(kù)鎖資源,放寬分布式事務(wù)鎖協(xié)議,提高業(yè)務(wù)并發(fā)性能。

還是以上面的例子舉例:

第一階段:檢查用戶(hù)資金,如果資金充足,凍結(jié)用戶(hù)本次交易資金,這筆資金被業(yè)務(wù)隔離,不允許除本事務(wù)之外的其它并發(fā)事務(wù)動(dòng)用。

第二階段:扣除第一階段預(yù)凍結(jié)的用戶(hù)資金,增加賣(mài)家資金,完成交易。 采用業(yè)務(wù)加鎖的方式,隔離用戶(hù)凍結(jié)資金,在第一階段結(jié)束后直接釋放底層資源鎖,該用戶(hù)和賣(mài)家的其他交易都可以立刻并發(fā)執(zhí)行,而不用等到整個(gè)分布式事務(wù)結(jié)束,可以獲得更高的并發(fā)交易能力。

3.2.3 一致性

再來(lái)看看 TCC 分布式事務(wù)模型下的一致性實(shí)現(xiàn)。與 XA 協(xié)議實(shí)現(xiàn)一致性第一層語(yǔ)義類(lèi)似,通過(guò)原子性保證事務(wù)的原子提交、業(yè)務(wù)隔離性控制事務(wù)的并發(fā)訪問(wèn),實(shí)現(xiàn)分布式事務(wù)的一致性狀態(tài)轉(zhuǎn)變。

至于第二層語(yǔ)義:事務(wù)的中間狀態(tài)不能被觀察到。我們來(lái)看看,在 SOA分布式應(yīng)用環(huán)境下是否是必須的。

還是以賬務(wù)服務(wù)舉例。轉(zhuǎn)賬業(yè)務(wù)(用戶(hù) A ? 用戶(hù) B),由交易服務(wù)和賬務(wù)服務(wù)組成分布式事務(wù),交易服務(wù)作為主業(yè)務(wù)服務(wù),賬務(wù)服務(wù)作為從業(yè)務(wù)服務(wù),賬務(wù)服務(wù)的 Try 操作預(yù)凍結(jié)用戶(hù) A 的資金;Commit 操作扣除用戶(hù) A 的預(yù)凍結(jié)資金,增加用戶(hù) B 的可用資金;Cancel 操作解凍用戶(hù) A 的預(yù)凍結(jié)資金。

當(dāng)賬務(wù)服務(wù)執(zhí)行完 Try 階段后,交易主業(yè)務(wù)就可以 Commit 了,然后由TCC 框架調(diào)用賬務(wù)的 Commit 階段。在賬務(wù) Commit 階段還沒(méi)執(zhí)行結(jié)束的時(shí)候,用戶(hù) A 可以查詢(xún)到自己的余額已扣除,但是,此時(shí)用戶(hù) B 的可用資金還沒(méi)增加。

從系統(tǒng)的角度來(lái)看,確實(shí)有問(wèn)題與不確定性。在第一階段執(zhí)行結(jié)束到第二階段執(zhí)行結(jié)束之間,有一段時(shí)間的延時(shí),在這段時(shí)間內(nèi),看似任何用戶(hù)都不享有這筆資產(chǎn)。

但是,從用戶(hù)的角度來(lái)考慮這個(gè)問(wèn)題的話(huà),這個(gè)時(shí)間間隔可能就無(wú)所謂或者根本就不存在。特別是當(dāng)這個(gè)時(shí)間間隔僅僅是幾秒鐘,對(duì)于具體溝通資產(chǎn)轉(zhuǎn)移的用戶(hù)來(lái)講,這個(gè)過(guò)程是隱蔽的或確實(shí)可以接受的,且保證了結(jié)果的最終一致性。

當(dāng)然,對(duì)于這樣的系統(tǒng),如果確實(shí)需要查看系統(tǒng)的某個(gè)一致性狀態(tài),可以采用額外的方法實(shí)現(xiàn)。

一般來(lái)講,服務(wù)之間的一致性比服務(wù)內(nèi)部的一致性要更加容易弱化,這也是為什么 XA 等直接在資源層面上實(shí)現(xiàn)通用分布式事務(wù)的模型會(huì)注重一致性的保證,而當(dāng)上升到服務(wù)層面,服務(wù)與服務(wù)之間已經(jīng)實(shí)現(xiàn)了功能的劃分,邏輯的解耦,也就更容易弱化一致性,這就是 SOA 架構(gòu)下 BASE 理論的最終一致性思想。

BASE 理論是指 BA(Basic Availability,基本業(yè)務(wù)可用性);S(Soft state,柔性狀態(tài));E(Eventual consistency,最終一致性)。該理論認(rèn)為為了可用性、性能與降級(jí)服務(wù)的需要,可以適當(dāng)降低一點(diǎn)一致性的要求,即“基本可用,最終一致”。

業(yè)內(nèi)通常把嚴(yán)格遵循 ACID 的事務(wù)稱(chēng)為剛性事務(wù);而基于 BASE 思想實(shí)現(xiàn)的事務(wù)稱(chēng)為柔性事務(wù)。柔性事務(wù)并不是完全放棄了 ACID,僅僅是放寬了一致性要求:事務(wù)完成后的一致性嚴(yán)格遵循,事務(wù)中的一致性可適當(dāng)放寬;

3.2.4 小結(jié)

TCC 分布式事務(wù)模型的業(yè)務(wù)實(shí)現(xiàn)特性決定了其可以跨 DB、跨服務(wù)實(shí)現(xiàn)資源管理,將對(duì)不同的 DB 訪問(wèn)、不同的業(yè)務(wù)操作通過(guò) TCC 模型協(xié)調(diào)為一個(gè)原子操作,解決了分布式應(yīng)用架構(gòu)場(chǎng)景下的事務(wù)問(wèn)題。

TCC 模型通過(guò) 2PC 原子提交協(xié)議保證分布式事務(wù)的的原子性,把資源層的隔離性上升到業(yè)務(wù)層,交給業(yè)務(wù)邏輯來(lái)實(shí)現(xiàn)。TCC 的每個(gè)操作對(duì)于資源層來(lái)說(shuō),就是單個(gè)本地事務(wù)的使用,操作結(jié)束則本地事務(wù)結(jié)束,規(guī)避了資源層在 2PC 和 2PL 下對(duì)資源占用導(dǎo)致的性能低下問(wèn)題。

同時(shí),TCC 模型也可以根據(jù)業(yè)務(wù)需要,做一些定制化的功能,比如交易異步化實(shí)現(xiàn)削峰填谷等。

但是,業(yè)務(wù)接入 TCC 模型需要拆分業(yè)務(wù)邏輯成兩個(gè)階段,并實(shí)現(xiàn) Try、Confirm、Cancel 三個(gè)接口,定制化程度高,開(kāi)發(fā)成本高。

四. 總結(jié)

本文首先介紹了典型的分布式事務(wù)的架構(gòu)場(chǎng)景。分布式事務(wù)剛開(kāi)始是為解決單服務(wù)多數(shù)據(jù)庫(kù)資源的場(chǎng)景而誕生的。隨著技術(shù)的發(fā)展,特別是 SOA 分布式應(yīng)用架構(gòu)以及微服務(wù)時(shí)代的到來(lái),服務(wù)變成了基本業(yè)務(wù)單元。因此,又產(chǎn)生了跨服務(wù)的分布式事務(wù)需求。然后從 XA 和 TCC 兩種常用的分布式事務(wù)模型入手,介紹了其實(shí)現(xiàn)機(jī)制,著重分析了各模型是如何實(shí)現(xiàn)分布式事務(wù) ACID 特性的。

©著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
3人點(diǎn)贊
總資產(chǎn)15共写了25.6W字获得907个赞共4,622个粉丝
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,463評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,009評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,778評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,218評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,436評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,795評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,993評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,229評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,659評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,917評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,687評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,990評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容