本文以一個實(shí)際業(yè)務(wù)問題來談?wù)勈聞?wù)該如何處理。對接外部系統(tǒng)是是不可避免的,從廣泛意義上來說,外部系統(tǒng)范圍很大,中間件(數(shù)據(jù)庫)也屬于外部系統(tǒng)。當(dāng)我們討論事務(wù)時(shí),通常我們將那些沒有支持事務(wù)的系統(tǒng)稱為外部系統(tǒng),業(yè)務(wù)系統(tǒng)基本上都是外部系統(tǒng)。
有這樣一套系統(tǒng),以gitlab
為底層系統(tǒng), 在gitlab project
的基礎(chǔ)上封裝了代碼倉,系統(tǒng)對其中一些與gitlab關(guān)聯(lián)的數(shù)據(jù)進(jìn)行了落表。創(chuàng)建代碼倉的邏輯過程比較復(fù)雜,首先通過gitlab創(chuàng)建代碼倉(其中返回的代碼倉id需要落庫),系統(tǒng)表code_repo
插入記錄,創(chuàng)建gitlabhook
,系統(tǒng)表member
插入記錄(維護(hù)系統(tǒng)用戶和對應(yīng)代碼倉的關(guān)系),創(chuàng)建多個gitlabbranch
(系統(tǒng)業(yè)務(wù),初始化代碼倉可以初始化多個分支),系統(tǒng)表label
插入記錄。
以上大概說明整個業(yè)務(wù)流程, gitlab接入的方式采用HTTP
,不采用直接對接gitlab數(shù)據(jù)庫的原因是,其創(chuàng)建項(xiàng)目和分支業(yè)務(wù)邏輯復(fù)雜,梳理代價(jià)很大。對接任何系統(tǒng)其實(shí)本質(zhì)上可以概括為兩種:
對接方式 | 優(yōu)勢 | 缺點(diǎn) |
---|---|---|
上游系統(tǒng)提供的接口 | 不需要關(guān)注上游系統(tǒng)的自身義務(wù)邏輯,維護(hù)只需要關(guān)注接口版本 | 靈活性較差 |
上游系統(tǒng)底層存儲(數(shù)據(jù)庫,文件等) | 需要梳理和維護(hù)上游系統(tǒng)業(yè)務(wù)邏輯,維護(hù)是代碼層面的 | 靈活性、可控性很好 |
,數(shù)據(jù)庫采用mysql
。 在不考慮異常的情況,整個業(yè)務(wù)流程還是比較清晰的,但是分布式的核心就是處理各種異常情況,這也是分布式復(fù)雜的地方。因?yàn)榉植际降木W(wǎng)絡(luò)環(huán)境是很復(fù)雜的。我們很保證底層系統(tǒng)的可用性。在這里,當(dāng)gitlab其中的接口出現(xiàn)異常,系統(tǒng)仍落庫顯然是不合理的,同樣的當(dāng)數(shù)據(jù)庫發(fā)生異常,gitlab數(shù)據(jù)存在也是不合理的,分布式事務(wù)的核心要解決數(shù)據(jù)一致性。
解決還需要與當(dāng)前的項(xiàng)目架構(gòu)不能沖突。目前各服務(wù)還沒有拆分,運(yùn)行。數(shù)據(jù)庫也沒有拆分。其架構(gòu)仍是單體架構(gòu)模式,設(shè)計(jì)時(shí)考慮了后期的微服務(wù)拆分。目前主要問題是解決Gitlab
和DB
之間的數(shù)據(jù)一致性,其復(fù)雜度沒有微服務(wù)多DB的高。
事務(wù)的概念來自數(shù)據(jù)庫事務(wù),在數(shù)據(jù)庫事務(wù)定義中,事務(wù)是一個執(zhí)行的邏輯單元
,它需要提供一個一致、可靠的數(shù)據(jù)操作,它主要包括下面兩個目標(biāo):
當(dāng)出現(xiàn)任何錯誤,包括系統(tǒng)宕機(jī)、部分失敗,都能保證左右的數(shù)據(jù)修改都能夠恢復(fù)到未修改的狀態(tài);
不通的事務(wù)并發(fā)處理相同的數(shù)據(jù)時(shí),提供適當(dāng)?shù)母綦x機(jī)制。 我們常說的ACID,其實(shí)是某些數(shù)據(jù)庫特有的事務(wù)實(shí)現(xiàn)方式,也就是實(shí)現(xiàn)了原子性、一致性、隔離性和持久性。 dan 分布式事務(wù),一直是實(shí)現(xiàn)分布式系統(tǒng)過程中最大的挑戰(zhàn),在單個數(shù)據(jù)源的系統(tǒng)中,只要該數(shù)據(jù)源支持事務(wù),例如大部分關(guān)系型數(shù)據(jù)庫,一些MQ服務(wù)(redis,mysql,activeMQ
等),我們實(shí)現(xiàn)事務(wù)相對容易。那么我們?nèi)绾卧诜植际较到y(tǒng)中實(shí)現(xiàn)事務(wù)呢?這就要從分布式系統(tǒng)的原則說起,目前主要有BASE原理 ACP原理
。其中ACP是:
A:可用性(Availability)
B:一致性(Consistency)
C:分區(qū)容錯性(Tolerance of network Partition) ruan zhuang t愛 A和P沒什么好說的,就是分布式系統(tǒng)的基本特性,C(一致性)指在分布式系統(tǒng)中,多個節(jié)點(diǎn)之間的數(shù)據(jù)的一致性,包括一個節(jié)點(diǎn)修改的數(shù)據(jù),通過另一個節(jié)點(diǎn)訪問的時(shí)候也能夠看到;以及當(dāng)一個操作需要修改多個數(shù)據(jù)源的數(shù)據(jù),多個修改都能夠同時(shí)完成或者同時(shí)不完成。
這里的一致性,我們可以看作是數(shù)據(jù)庫事務(wù)的ACID特性中,原子性、一致性甚至是隔離性的統(tǒng)一。如果以ACID標(biāo)準(zhǔn)實(shí)現(xiàn)分布式系統(tǒng),在現(xiàn)實(shí)中是不可能的。其中原子性就沒法實(shí)現(xiàn),如果一個業(yè)務(wù)請求,要修改多個數(shù)據(jù)庫中的數(shù)據(jù),那么這多個數(shù)據(jù)庫操作,就無法實(shí)現(xiàn)原子性,勢必會有一個先后,這一點(diǎn)點(diǎn)時(shí)間就違反了原子性。
所以,我們往往無法在分布式系統(tǒng)中實(shí)現(xiàn)完全的一致性,所以就有了BASE理論,BASE是BasicallAvailable(基本可用),SOftstate(軟狀態(tài))和Eventually consistent(最終一致性)三個短語的縮寫。BASE理論是對CAP中一致性和可用性權(quán)衡的結(jié)果,要求實(shí)現(xiàn)最終一致性即可。
其中,SoftState(軟狀態(tài))是指,在一個業(yè)務(wù)操作過程中,允許出現(xiàn)一個中間狀態(tài),也就是軟狀態(tài),而不是要求原子性那樣,要么完成要么不完成。例如在下單的時(shí)候,出現(xiàn)一個正在處理
狀態(tài)。由于有這個軟狀態(tài),那我的一致性就不是要求搶一致性,而是最終一致性,也就是說,只要最終這個請求能夠處理完,所有數(shù)據(jù)狀態(tài)都是處理完的狀態(tài);如果期間出錯了,所有的數(shù)據(jù)也都一致,該失敗的失敗,該退錢的退錢,該重置的重置。 確定分布式系統(tǒng)的實(shí)現(xiàn)原則是最終一致性以后,同時(shí)也明確了我們實(shí)現(xiàn)分布式事務(wù)的原則,也是最終一致性。其實(shí),不管數(shù)據(jù)庫事務(wù)的ACID特性,還是分布式事務(wù)的最終一致性,都是根據(jù)事務(wù)的定義和它的兩個目標(biāo),所采用的不通的實(shí)現(xiàn)方式。
那我們該如何實(shí)現(xiàn)這個最終一致性呢?
首先,任何一個分布式系統(tǒng),總是由一個個的系統(tǒng)組成,也就是一個個的服務(wù),這些服務(wù)也可以部署多個實(shí)例。同時(shí),我們整個系統(tǒng)也需要一定的方式相互通信。我們采用接口的方式,也可以通過MQ之類的消息中間件通信。但是無論怎樣,分布式系統(tǒng)會涉及多個數(shù)據(jù)源。
對于這種每個服務(wù)訪問多個數(shù)據(jù)源的情況,其實(shí)就是一個最簡單的分布式事務(wù)的場景。如果大家在網(wǎng)上搜“Spring分布式事務(wù)實(shí)現(xiàn)”,搜索到結(jié)果也就是在說這個場景下的分布式事務(wù)實(shí)現(xiàn)過程。要實(shí)現(xiàn)這個事務(wù),首先需要對Spring的事務(wù)機(jī)制有一定的了解。對于這種情況,最簡單的就是使用Springde JTA事務(wù)管理,但是我們知道。JTAs事務(wù)管理是通過兩階段提交實(shí)現(xiàn)的,在很多情況下,他的效率是很低的。因?yàn)樗诙鄠€數(shù)據(jù)源秀修改數(shù)據(jù)的時(shí)候,這些數(shù)據(jù)一直處在被鎖的狀態(tài),直到多個數(shù)據(jù)源的事務(wù)都提交完成,才會釋放。
如果不用JTA,Spring也給我們提供了幾種方式,來近似的實(shí)現(xiàn)分布式事務(wù),例如:
事務(wù)同步,也就是提交一個事務(wù)的時(shí)候,通過Listener等方式通知另一個事務(wù)也提交。但是這種情況下,如果第二個事務(wù)提交出錯了,第一個事務(wù)就無法回滾了,因?yàn)樗呀?jīng)提交完成了
鏈?zhǔn)绞聞?wù),也就是將多個事務(wù),包裝在一個鏈?zhǔn)绞聞?wù)管理器中,當(dāng)提交事務(wù)的時(shí)候,一次提交里面的事務(wù),對于這種情況,也存在上面所說的問題
所以,使用spring在單服務(wù)多數(shù)據(jù)源的情況下,實(shí)現(xiàn)分布式事務(wù),實(shí)際上沒辦法完全實(shí)現(xiàn)事務(wù)的,因?yàn)槌鲥e的時(shí)候不能夠保證。那么這時(shí)候,就需要通過其他機(jī)制來補(bǔ)充。比如重試,自己處理錯誤和異常。
大家可以試想一下,分布式系統(tǒng)越復(fù)雜,它出錯的情況就越多,我們需要考慮的補(bǔ)救措施就越多。這種修修補(bǔ)補(bǔ)的實(shí)現(xiàn)分布式事務(wù)的最終一致性的做法,始終不是一個好做法。但是,使用Spring解決單服務(wù)的分布式系統(tǒng),始終是分布式事務(wù)實(shí)現(xiàn)的基礎(chǔ)。我們可以用其他的模式來方便我們解決分布式事務(wù),但是在每個服務(wù)中,我們還是要經(jīng)常使用事務(wù)同步、鏈?zhǔn)绞聞?wù)等來實(shí)現(xiàn)事務(wù)。我們用Spring來保證絕大數(shù)情況下的事務(wù)問題,而對于特殊的錯誤情況,就采用其他的模式來解決。
剛才說了我們使用其他模式來處理分布式事務(wù)問題,主要有下面五種模式,參考 分布式事務(wù)參考 :
XA方案
TCC方案
本地消息表
可靠消息最終一直方案
最大努力通知方案
由于目前是單DB,可以盡最大限度利用單DB事務(wù)特性,Spring事務(wù)管理中介紹了有兩種事務(wù)管理方式(programmatically and declarative )。 雖然官方文檔建議使用申明式事務(wù)管理方式,但是我們在回滾數(shù)據(jù)庫事務(wù)需要執(zhí)行其他操作時(shí),如API的反操作,手動方式才能夠?qū)崿F(xiàn)。
CoderepoService
中提供的創(chuàng)建代碼倉接口createCodeRepo
,主要包含①②③④操作,其中只有一個DB操作④,使用數(shù)據(jù)庫事務(wù)無法滿足情況。 例如當(dāng)①②執(zhí)行成功,③執(zhí)行失敗,這是通過異常事務(wù)回滾無法回滾Gitlab中的數(shù)據(jù)。所以必須手動回滾,處理邏輯如下。我們Spring數(shù)據(jù)庫事務(wù),保證DB操作, 當(dāng)③④失敗時(shí)手動捕獲異常(回滾gitlab數(shù)據(jù)),并拋出系統(tǒng)業(yè)務(wù)異常(使事務(wù)生效)。
這里涉及的Gitlab操作對應(yīng)一個回滾操作deleteGitlabProject()
,DB通過事務(wù)回滾。
本文討論問題類似單服務(wù)多DB場景,不同的是gitlab數(shù)據(jù)與通是保證通過HTTP
調(diào)用的,并沒有實(shí)現(xiàn)事務(wù)。 如何保證DB與第三方系統(tǒng)數(shù)據(jù)保持一致性的問題,盡量較小的代碼改動。在微服務(wù)多數(shù)據(jù)源的情況下不能夠滿足需求,需要根據(jù)業(yè)務(wù)選型。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/127925.html
摘要:是的簡稱,運(yùn)行環(huán)境,為的運(yùn)行提供了所需的環(huán)境。分割字符串,返回分割后的字符串?dāng)?shù)組。當(dāng)計(jì)算的值相同時(shí),我們稱之為沖突,的做法是用鏈表和紅黑樹存儲相同的值的。迭代器取代了集合框架中的,迭代器允許調(diào)用者在迭代過程中移除元素。 Java基礎(chǔ)1.JDK和JRE有什么區(qū)別? JDK 是java development kit的簡稱,java開發(fā)工具包,提供java的開發(fā)環(huán)境和運(yùn)行環(huán)境。JRE 是j...
摘要:面試總結(jié)最近兩周面試了幾家公司高級工程師的職位,主要有宜信網(wǎng)信金融阿里高德口袋購物。目前有部分公司已經(jīng)面試通過,兩家在等消息。今天趁熱把常見面試內(nèi)容總結(jié)一下??梢杂脕硗瓿山y(tǒng)一命名服務(wù)狀態(tài)同步服務(wù)集群管理分布式應(yīng)用配置項(xiàng)等管理工作。 面試總結(jié) 最近兩周面試了幾家公司Java高級工程師的職位,主要有宜信、網(wǎng)信金融、阿里高德、口袋購物。目前有部分公司已經(jīng)面試通過,兩家在等消息。今天趁熱把常見...
摘要:中大致分為兩部分事務(wù)管理器和本地資源管理器。具體實(shí)現(xiàn)分布式事務(wù)框架的核心功能是對本地事務(wù)的協(xié)調(diào)控制,框架本身并不創(chuàng)建事務(wù),只是對本地事務(wù)做協(xié)調(diào)控制。 Spring Cloud 分布式事務(wù)管理 在微服務(wù)如火如荼的情況下,越來越多的項(xiàng)目開始嘗試改造成微服務(wù)架構(gòu),微服務(wù)即帶來了項(xiàng)目開發(fā)的方便性,又提高了運(yùn)維難度以及網(wǎng)絡(luò)不可靠的概率. @[toc]在說微服務(wù)的優(yōu)缺點(diǎn)時(shí),有對比才會更加明顯,首先...
摘要:使用事務(wù)管理器是支持的一個流行的開源事務(wù)管理器實(shí)現(xiàn),你可以使用啟動器向項(xiàng)目添加適當(dāng)?shù)囊蕾図?xiàng),與和一樣,將自動配置并對進(jìn)行后處理,以確保啟動和關(guān)閉順序是正確的。 37. 用JTA分布式事務(wù) 通過使用Atomikos或Bitronix嵌入式事務(wù)管理器,Spring Boot支持跨多個XA資源的分布式JTA事務(wù),在部署到合適的Java EE應(yīng)用服務(wù)器時(shí)也支持JTA事務(wù)。 當(dāng)檢測到JTA環(huán)境時(shí)...
摘要:只有在事務(wù)確定正確提交之后,才會顯示該事務(wù)對數(shù)據(jù)的改變。不允許不一致現(xiàn)象的出現(xiàn)。 @[TOC] 為什么寫這系列的文章 在日常的工作和開發(fā)中,接觸最多的便是與數(shù)據(jù)庫打交道,無論你使用什么框架進(jìn)行開發(fā)都繞不開事務(wù)的管理. 在Java開發(fā)中你可能會接觸很多ORM框架,無論是Hibernate、MyBatis、還是Spring Jdbc 都會遇到事務(wù)的相關(guān)操作,再到中大型項(xiàng)目,你還會遇到單一數(shù)...
閱讀 1582·2025-02-07 13:29
閱讀 1007·2024-11-07 18:25
閱讀 131501·2024-02-01 10:43
閱讀 1360·2024-01-31 14:58
閱讀 1147·2024-01-31 14:54
閱讀 83574·2024-01-29 17:11
閱讀 3875·2024-01-25 14:55
閱讀 2392·2023-06-02 13:36