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