本地事務
事務Transaction由一組SQL組成,具有四個ACID特性
ACID
Atomicity 原子性 構成事務的一組SQL,要么全部生效,要么全不生效,不會出現部分生效的情況
Consistency 一致性 資料庫經過事務操作后從一種狀態轉變為另一個狀態,可以說原子性是從行為上描述,而一致性是從結果上描述
isolation 隔離性 事務操作的資料物件 相對于 其他事務操作的資料物件相互隔離,互不影響
durability 持久性 事務提交后,其結果就是永久性的,即使發生宕機(非磁盤損壞)
事務實作
對于MySQL資料庫(InnoDB存盤引擎)而言,隔離性是通過不同粒度的鎖機制來實作事務間的隔離;原子性、一致性和持久性通過redo log 重做日志和undo log回滾日志來保證的,
redo log 當資料庫對資料做修改的時候,需要把資料頁從磁盤讀到buffer pool中,然后在buffer pool中進行修改,那么這個時候buffer pool中的資料頁就與磁盤上的資料頁內容不一致,稱buffer pool的資料頁為dirty page 臟資料,如果這個時候發生非正常的DB服務重啟,那么這些資料還沒在記憶體,并沒有同步到磁盤檔案中(注意,同步到磁盤檔案是個隨機IO),也就是會發生資料丟失,如果這個時候,能夠在有一個檔案,當buffer pool 中的data page變更結束后,把相應修改記錄記錄到這個檔案(注意,記錄日志是順序IO),那么當DB服務發生crash的情況,恢復DB的時候,也可以根據這個檔案的記錄內容,重新應用到磁盤檔案,資料保持一致,
undo log undo日志用于存放資料被修改前的值,如果修改出現例外,可以使用undo日志來實作回滾操作,保證事務的一致性,另外InnoDB MVCC事務特性也是基于undo日志實作的,undo日志分為insert undo log (insert陳述句產生的日志,事務提交后直接洗掉)和 update undo log(delete和update陳述句產生的日志,由于該undo log可能提供MVVC機制使用,所以不能再事務提交時洗掉),
問題引入
CAP理論
CAP原則又稱CAP定理,指的是在一個分布式系統中,一致性(Consistency)、可用性(Availability)、磁區容錯性(Partition tolerance),CAP 原則指的是,這三個要素最多只能同時實作兩點,不可能三者兼顧,但由于在分布式系統中,磁區容錯性必然存在,所以只能在一致性和可用性妥協,
傳統的DBMS,如MySQL其實CA組合,在主從架構下,讀寫分離的情況下,是犧牲一定的一致性的(主從延遲),
Base理論
base available 基本可用 分布式系統在出現故障時,允許損失部分可用功能,保證核心功能可用
soft state 軟狀態 允許系統中存在中間狀態,這個狀態不影響系統可用性
eventually consistent 最終一致性 系統的中間狀態經過短暫的時間后到達一致狀態
如何解決
場景舉例
考慮這樣一種業務場景,系統A呼叫系統B的退款服務進行退款,系統A更改內部退款狀態,接著呼叫系統C的短信服務通知用戶,
在這樣的一個場景下,由于網路不可靠的必然存在,存在A、B、C三個系統之間一致性的問題,
本地表
針對上述場景,設計兩張表 退款記錄表 和 短信發送記錄表 以及 相應的補償Job
具體實作程序:
- 新增退款記錄表,狀態為處理中
- 呼叫系統B的退款服務進行退款
- 更新退款記錄狀態為對應的狀態(成功/失敗)
- 如果退款成功,則新增短信發送記錄,記錄狀態為待發送
- 呼叫系統C的短信服務,發送短信
- 更新短信發送記錄為已發送
退款補償Job 查詢退款記錄表中處理中的記錄,呼叫系統B的退款服務 退款成功處理:
- 新增短信發送記錄,記錄狀態為待發送
- 呼叫系統C的短信服務,發送短信
- 更新短信發送記錄為已發送
短信通知補償Job 查詢短信發送記錄中待發送的記錄,呼叫系統C的短信服務
- 呼叫系統C的短信服務,發送短信
- 更新短信發送記錄為已發送
注意:
- 系統B和系統C需要根據呼叫方傳的uuid支持冪等
- 系統A、B、C會出現短暫的不一致,但最終一致
事務訊息
可以將其視為兩階段提交訊息實作,以確保分布式系統中的最終一致性,事務性訊息可確保本地事務的執行和訊息的發送可以原子方式執行,
但是由于事務訊息異步的特性,呼叫方拿不到消費方的處理結果,適用于不關心對方的回傳結果/對方負責保證處理成功
針對上述場景,增加兩個事務訊息的方式解決一致性問題,系統A通過發送事務訊息的方式與系統B和系統C進行互動
具體實作程序:
- 發送退款的事務訊息
- 新增退款記錄,狀態為:處理中
- Commit退款事務訊息
提供MQ事務callback
退款callback查詢
- 有退款記錄且為處理中則Commit
- 其他則Rollback
發送短信callback查詢
- 有退款記錄且成功則Commit
- 其他則Rollback
退款同步Job
查詢退款記錄表中處理中的記錄,呼叫系統B的退款查詢介面 同步狀態 其中退款成功處理:
- 發送短信的事務訊息
- 更新退款記錄為成功
- Commit短信事務訊息
相關理論
二階段提交
二階段提交是解決分布式事務問題的重要理論基礎,但也存在著明顯的問題:
- 阻塞問題,參與者將協議訊息發送給協調器后,它將阻塞直到收到提交或回滾,只能依賴協調者的超時機制
- 協調者單點問題,如果協調者出現故障,則某些參與者將一直無法收到提交或回滾的訊息,
為了解決二階段提交出現的問題,又有了三階段提交(Three-phase commit):
- 解決阻塞問題:將2PC中的第一階段一分為二,提供了一個CanCommit階段,此階段并不鎖定資源,這樣可以大幅降低了阻塞概率
- 解決單點問題:在參與者這邊也引入了超時機制
DTP Model
X / Open分布式事務處理DTP(Distributed Transaction Processing)模型是一種軟體體系架構,已經成為事實上的事務模型組件的行為標準,它允許多個應用程式共享由多個資源管理器提供的資源,并允許其作業被協調為全域事務,
ApplicationProgram(AP) 應用程式定義了事務邊界并指定構成事務的操作
ResourceManager(RM) 資源管理器用來管理我們需要訪問的共享資源,我們可以將它理解為關系資料庫、檔案存盤系統、訊息佇列、列印機等
TransactionManagger(TM) 事務管理器是一個獨立的組件,他為事務分配識別符號并監視事務的執行情況,負責事務完成和故障恢復
CommunicationResourceManager(CRM) 通信資源管理器控制一個或多個 TM domain 之間分布式應用的通信,
XA Specification
XA規范是X/Open關于分布式事務處理 (DTP)的規范,規范描述了全域的事務管理器與區域的資源管理器之間的介面,XA規范的目的是允許多個資源(如資料庫,應用服務器,訊息佇列,等等)在同一事務中訪問,這樣可以使ACID屬性跨越應用程式而保持有效,XA使用兩階段提交來保證所有資源同時提交或回滾任何特定的事務,
XA規范描述了資源管理器要支持事務性訪問所必需做的事情,
TCC
saga
在 Saga 模式下,分布式事務內有多個參與者,每一個參與者都是一個沖正補償服務,需要用戶根據業務場景實作其正向操作和逆向回滾操作,
分布式事務執行程序中,依次執行各參與者的正向操作,如果所有正向操作均執行成功,那么分布式事務提交,如果任何一個正向操作執行失敗,那么分布式事務會去退回去執行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務回到初始狀態,
Saga 模式下分布式事務通常是由事件驅動的,各個參與者之間是異步執行的,Saga 模式是一種長事務解決方案,
Saga模式的優勢是:
- 一階段提交本地資料庫事務,無鎖,高性能;
- 參與者可以采用事務驅動異步執行,高吞吐;
- 補償服務即正向服務的“反向”,易于理解,易于實作;
缺點:
- Saga 模式由于一階段已經提交本地資料庫事務,且沒有進行“預留”動作,所以不能保證隔離性,
開源專案
seata
Seata 是一款開源的分布式事務解決方案,致力于在微服務架構下提供高性能和簡單易用的分布式事務服務,支持AT、TCC、SAGA、XA四種模式,對微服務框架支持友好,
如下圖所示,Seata 中有三大模塊,分別是 TM、RM 和 TC, 其中 TM 和 RM 是作為 Seata 的客戶端與業務系統集成在一起,TC 作為 Seata 的服務端獨立部署,
TC - 事務協調者 維護全域和分支事務的狀態,驅動全域事務提交或回滾,
TM - 事務管理器 定義全域事務的范圍:開始全域事務、提交或回滾全域事務,
RM - 資源管理器 管理分支事務處理的資源,與TC交談以注冊分支事務和報告分支事務的狀態,并驅動分支事務提交或回滾,
在 Seata 中,分布式事務的執行流程:
- TM 開啟分布式事務(TM 向 TC 注冊全域事務記錄);
- 按業務場景,編排資料庫、服務等事務內資源(RM 向 TC 匯報資源準備狀態 );
- TM 結束分布式事務,事務一階段結束(TM 通知 TC 提交/回滾分布式事務);
- TC 匯總事務資訊,決定分布式事務是提交還是回滾;
- TC 通知所有 RM 提交/回滾 資源,事務二階段結束;
AT模式
AT 模式是一種無侵入的分布式事務解決方案,在 AT 模式下,用戶只需關注自己的“業務 SQL”,用戶的 “業務 SQL” 作為一階段,Seata 框架會自動生成事務的二階段提交和回滾操作,
一階段:業務資料和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源, 二階段:提交異步化,非常快速地完成,回滾通過一階段的回滾日志進行反向補償,
在一階段,Seata 會攔截“業務 SQL”,首先決議 SQL 語意,找到“業務 SQL”要更新的業務資料,在業務資料被更新前,將其保存成“before image”,然后執行“業務 SQL”更新業務資料,在業務資料更新之后,再將其保存成“after image”,最后生成行鎖,以上操作全部在一個資料庫事務內完成,這樣保證了一階段操作的原子性,
TCC模式
一個分布式的全域事務,整體是 兩階段提交 的模型,全域事務是由若干分支事務組成的,分支事務要滿足 兩階段提交 的模型要求,即需要每個分支事務都具備自己的:
一階段 prepare 行為 二階段 commit 或 rollback 行為
TCC 模式,不依賴于底層資料資源的事務支持:
- 一階段 prepare 行為:呼叫 自定義 的 prepare 邏輯,
- 二階段 commit 行為:呼叫 自定義 的 commit 邏輯,
- 二階段 rollback 行為:呼叫 自定義 的 rollback 邏輯,
所謂 TCC 模式,是指支持把 自定義 的分支事務納入到全域事務的管理中,
Saga模式
目前SEATA提供的Saga模式是基于狀態機引擎來實作的,機制是:
- 通過狀態圖來定義服務呼叫的流程并生成 json 狀態語言定義檔案
- 狀態圖中一個節點可以是呼叫一個服務,節點可以配置它的補償節點
- 狀態圖 json 由狀態機引擎驅動執行,當出現例外時狀態引擎反向執行已成功節點對應的補償節點將事務回滾 (例外發生時是否進行補償也可由用戶自定義決定)
- 可以實作服務編排需求,支持單項選擇、并發、子流程、引數轉換、引數映射、服務執行狀態判斷、例外捕獲等功能
狀態機引擎原理
- 圖中的狀態圖是先執行stateA, 再執行stateB,然后執行stateC
- "狀態"的執行是基于事件驅動的模型,stateA執行完成后,會產生路由訊息放入EventQueue,事件消費端從EventQueue取出訊息,執行stateB
- 在整個狀態機啟動時會呼叫Seata Server開啟分布式事務,并生產xid, 然后記錄"狀態機實體"啟動事件到本地資料庫
- 當執行到一個"狀態"時會呼叫Seata Server注冊分支事務,并生產branchId, 然后記錄"狀態實體"開始執行事件到本地資料庫
- 當一個"狀態"執行完成后會記錄"狀態實體"執行結束事件到本地資料庫, 然后呼叫Seata Server上報分支事務的狀態
- 當整個狀態機執行完成, 會記錄"狀態機實體"執行完成事件到本地資料庫, 然后呼叫Seata Server提交或回滾分布式事務
最后
關注公眾號:程式員白楠楠, 領取2020最新Java面試題手冊(200多頁PDF檔案),
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229653.html
標籤:Java
上一篇:Spring Boot 2.4.0 發布,組態檔重大調整,不要亂升級!!
下一篇:JavaAPI-工具類
