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