- 什麼是事務
事務基本理論:
1、從數據庫的角度(對數據庫來說): 一個 SQL 語句就是一個事務
2、從業務角度: 一個程序實現單元就是一個事務(一條或多個 SQL 組成)
事務特性:ACID 事務特性
1、原子性: 要麼都成功,要麼都失敗
2、一致性: 事務開啟之前對其他線程可見的狀態,中間狀態不可見,事務結束之後才可見。
3、隔離性: 事務與事務之間隔離的 (底層使用鎖)
4、持久性: 把數據存儲在磁盤
開發業務: 一般情況下,都使用本地事務(沒有解決分佈式事務)
如下:本地事務,單機事務 一個事務單元
![認識分佈式事務](http://p2.ttnews.xyz/loading.gif)
特點: 應用程序操作的是單一的數據源,讓多個操作是一個原子性操作。
思考問題
項目都使用分佈式架構的模式,數據一致性處理非常困難???
1、網絡抖動
2、網絡延遲
3、服務宕機(無法避免)
4、機器宕機
5、程序崩潰
6、異常異常
………………….
以上問題是必然會發生的,因此解決數據一致性問題才會如此困難? ---- 在處理數據一致
性的問題上面,必須有所取捨 ----
強一致性(基於數據庫) ----- CAP 理論(分佈式)----- Base 理論(最終一致性)
- CAP
在當前的軟件架構模式下,有狀態服務部署(分佈式部署模式下),無法同時保證可用性,
和一致性,必須有所取捨。
如果我們保證一致性,會存在分區的問題。
如果追求一致性:可讓數據完成同步後,大家在去讀去數據,損失一部分性能,換取一致性。
如果追求可用性:可以採用異步模式同步數據,只有主機進行讀操作,從機負責備份,監控主機,切換master,切換這一瞬間,從機是沒有主機部分數據的,因此會存在數據的丟失。
在互聯網項目,追求性能上提升,因此選擇可用性,提升項目性能。但是選擇可用性後,數據一致性會存在問題。如何解決呢??
- Base 理論
BASE 是 Basically Available(基本可用)、Soft state(軟狀態)和 Eventually consistent(最終一致性)三個短語的縮寫。
• 基本可用(Basically Available)指分佈式系統在出現不可預知故障的時候,允許損失部分可用性。
• 軟狀態( Soft State)指允許系統中的數據存在中間狀態,並認為該中間狀態的存在不會影響系統的整體可用性。
• 最終一致( Eventual Consistency)強調的是所有的數據更新操作,在經過一段時間的同步之後,最終都能夠達到一個一致的狀態
解決方案:
最大努力通知(非可靠消息、定期校對)
可靠消息最終一致性(異步確保型)
TCC(兩階段型、補償型)
- 分佈式事務場景
分佈事務基本定義:
當下互聯網絕大部分公司都進行了數據庫拆分和服務化(SOA),微服務。在這種情況下,完成某一個業務功能可能需要橫跨多個服務,操作多個數據庫。
這就涉及到到了分佈式事務,用需要操作的資源位於多個資源服務器上,而應用需要保證對於多個資源服務器的數據的操作,要麼全部成功,要麼全部失敗。本質上來說,分佈式事務就是為了保證不同資源服務器的數據一致性
從分佈式架構層面對分佈式事務進行分析:
![認識分佈式事務](http://p2.ttnews.xyz/loading.gif)
注意: 以上架構把一個事務單元拆分為多個子事務(微服務架構拆分),以上每一個子事務都屬於一個業務動作,在業務需求來說,要求這些業務動作要麼都成功,要麼都失敗。也就是說要求這 4 個事務,要麼都成功,要麼都失敗。
總結: 所謂的分佈式事務,其實就是保證多個子事務要麼都成功,要麼都失敗;
問: 以下的場景,是否屬於分佈式事務的場景???
場景 1:一個應用程序操作多個庫(redis,mysql,es,mq………..)
以上也屬於分佈式事務場景,解決 Redis,mysql 數據一致性的問題。使用本地事務,只能控制 MySQL 數據一致性 ,不能控制 Redis 數據一致性。因此 Redis mysql 如果存在業務的關聯性,必須保證 Redis,mysql 數據一致性。
場景 2: 應用程序操作的多個數據源,是否屬於分佈式事務?
以上的操作方式,是操作多個數據源(事務本質:數據庫的事務),因此 datasource1,datasource2
屬於不同的事務,這個 2 個事務相互沒有感知,因此這 2 個事務屬於隔離的狀態,是屬於不同進程的事務。因此這個屬於分佈式事務。
如何解決分佈式事務?
感知:
1、感知不同服務事務狀態,如果每一個服務事務都準備好了,統一通知大家一起提交。
2、業務補償機制
- 分佈式事務規範
- X/OPEN 事務模型
1)應用程序(Application Program : AP): 定義事務邊界(事務開始,結束)--- @Transactional @分佈式事務註解
2)資源管理器 (Resource Manager: RM):任何用來存儲數據的服務
3)事務管理器(Transaction Manager : TM): 監控事務進度,負責事務提交,回滾 ---TransactionManager
4)通信資源管理(Communcation Resource Manager : CRM)
5) 通信協議 (負責事務模型之間的通信協議)
X/open 組織把分佈式事務處理模型抽象成了上圖所示:AP,TM,RM 三者之間關係。
分佈式模式下: 微服務架構:鏈式調用 --- 存在如下的分佈式事務模型 --- 全局事務樹模
型
TM: 存在形式是什麼???
1)jar ----- 和應用程序集成在一起
2)服務形式 --- 第三方單獨部署
2. Xa接口規範
XA:定義了TM和RM交互接口規範【事務註冊、提交、回滾、事務結束.....】
XA標準:存儲的數據的服務都開放了支持分佈式事務接口規範 XA(MYSQL 、ORACLE)
TM 事務管理器也必須遵循XA的規範來調用事務控制器接口
x/open 組織制定 TM/RM 接口交互規範,用來處理分佈式事務。
1)xa_reg 註冊事務
2)xa_start 開啟事務
3)xa_close 關閉事務
……………………………………………………………..
思考: 如何沒有接口規範,會發生什麼???
RM(存儲數據的服務)
1)MYSQL
2)Oracle
3)SQL server
4)mq
TM (事務管理器)-- 廠商開發了很多事務管理器
XA 接口規範制定後:
Mysql5.7 實現 xa 接口規範,支持分佈式事務
Rocketmq 集成 xa 接口規範
數據庫分佈式支持:
3、2pc
兩階段提交協議(Two Phase Commit),XA 規範對其進行了優化。而從字面意思來理解,Two Phase Commit,就是將提交(commit)過程劃分為 2 個階段(Phase):
應用程序: 只需要定義事務邊界即可,一切事務執行,提交,回滾都交給 TM存在問題:
1、阻塞問題: TM 宕機,事務已經執行(上鎖),一直處於阻塞狀態,無法釋放。
2、數據一致性問題
Commit 階段,RM1 已經提交,RM1 由於網絡的原因,沒有送達提交信息,出現RM1,RM2 數據不一致的問題。
4、3pc
三階段提交(3PC)[Three-phase commit],是二階段提交(2PC)的改進版本。與兩階段提交不同的是,三階段提交有兩個改動點
- 引入超時機制。同時在協調者和參與者中都引入超時機制。
- 在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段之前各參與節點的狀態是一致的。也就是說,除了引入超時機制之外,3PC 把 2PC 的準備階段再次一分為二,這樣三階段提交就有 CanCommit、PreCommit、DoCommit 三個階段
CanCommit階段
3PC的CanCommit階段其實和2PC的準備階段很像。協調者向參與者發送commit請求,參與者如果可以提交就返回Yes響應,否則返回No響應。
事務詢問
協調者向參與者發送CanCommit請求。詢問是否可以執行事務提交操作。然後開始等待參與者的響應。
響應反饋 參與者接到CanCommit請求之後,正常情況下,如果其自身認為可以順利執行事務,則返回Yes響應,並進入預備狀態。否則反饋No
PreCommit階段
協調者根據參與者的反應情況來決定是否可以記性事務的PreCommit操作。根據響應情況,有以下兩種可能。
假如協調者從所有的參與者獲得的反饋都是Yes響應,那麼就會執行事務的預執行。
發送預提交請求 協調者向參與者發送PreCommit請求,並進入Prepared階段。
事務預提交 參與者接收到PreCommit請求後,會執行事務操作,並將undo和redo信息記錄到事務日誌中。
響應反饋 如果參與者成功的執行了事務操作,則返回ACK響應,同時開始等待最終指令。
doCommit階段
該階段進行真正的事務提交,也可以分為以下兩種情況。
執行提交
發送提交請求 協調接收到參與者發送的ACK響應,那麼他將從預提交狀態進入到提交狀態。並向所有參與者發送doCommit請求。
事務提交 參與者接收到doCommit請求之後,執行正式的事務提交。並在完成事務提交之後釋放所有事務資源。
響應反饋 事務提交完之後,向協調者發送Ack響應。
完成事務 協調者接收到所有參與者的ack響應之後,完成事務。
中斷事務 協調者沒有接收到參與者發送的ACK響應(可能是接受者發送的不是ACK響應,也可能響應超時),那麼就會執行中斷事務。
-
發送中斷請求 協調者向所有參與者發送abort請求
事務回滾 參與者接收到abort請求之後,利用其在階段二記錄的undo信息來執行事務的回滾操作,並在完成回滾之後釋放所有的事務資源。
反饋結果 參與者完成事務回滾之後,向協調者發送ACK消息
中斷事務 協調者接收到參與者反饋的ACK消息之後,執行事務的中斷。
在doCommit階段,如果參與者無法及時接收到來自協調者的doCommit或者rebort請求時,會在等待超時之後,會繼續進行事務的提交。(其實這個應該是基於概率來決定的,當進入第三階段時,說明參與者在第二階段已經收到了PreCommit請求,那麼協調者產生PreCommit請求的前提條件是他在第二階段開始之前,收到所有參與者的CanCommit響應都是Yes。(一旦參與者收到了PreCommit,意味他知道大家其實都同意修改了)所以,一句話概括就是,當進入第三階段時,由於網絡超時等原因,雖然參與者沒有收到commit或者abort響應,但是他有理由相信:成功提交的幾率很大。 )
2PC與3PC的區別
相對於2PC,3PC主要解決的單點故障問題,並減少阻塞,因為一旦參與者無法及時收到來自協調者的信息之後,他會默認執行commit。而不會一直持有事務資源並處於阻塞狀態。但是這種機制也會導致數據一致性問題,因為,由於網絡原因,協調者發送的abort響應沒有及時被參與者接收到,那麼參與者在等待超時之後執行了commit操作。這樣就和其他接到abort命令並執行回滾的參與者之間存在數據不一致的情況。
分佈式事務解決方案