本地事務:支持事務的參與者、伺服器、資源管理器(RM)和事務管理器(TM)位於單機之上,僅限對單一資料庫資源的訪問控制。就是表和資料庫位於一個伺服器上,事務的操作都在這一個伺服器上進行。
起初,事務僅限於對單一數據資源的訪問控制:
而我們的本地事務由資源管理器進行管理:
事務的ACID是通過InnoDB日誌和鎖來保證。事務的隔離性是通過事務的鎖機制實現的,持久性通過redo log(重做日誌)來實現,原子性和一致性通過Undo log來實現。UndoLog的原理很簡單,為了滿足事務的原子性,在操作任何數據之前,首先將數據備份到一個地方(這個存儲數據備份的地方稱為UndoLog)。然後進行數據的修改。如果出現了錯誤或者用戶執行了ROLLBACK語句,系統可以利用Undo Log中的備份將數據恢復到事務開始之前的狀態。 和Undo Log相反,RedoLog記錄的是新數據的備份。在事務提交前,只要將RedoLog持久化即可,不需要將數據持久化。當系統崩潰時,雖然數據沒有持久化,但是RedoLog已經持久化。系統可以根據RedoLog的內容,將所有數據恢復到最新的狀態。
本地事務主要限制在單個會話內,不涉及多個資料庫資源。但是在基於SOA(Service-Oriented Architecture,面向服務架構)的分布式應用環境下,越來越多的應用要求對多個資料庫資源,多個服務的訪問都能納入到同一個事務當中,分布式事務應運而生。
在開發中,為了降低單機的壓力,通常會進行分表分庫,將表分布在不同的資料庫中(資料庫有可能分布在不同的機器上),但是一個業務場景可能會處理不同庫中的表,事務的提交就不能在像單機那樣處理,因為涉及到多個伺服器的控制,要考慮伺服器之間的通信是否正常、網絡延時帶寬等因素,這些在單機上並沒有太大的影響。所以說多伺服器之間事務的控制變得相對複雜,分布式事務也就相應的出現。
比如原來單機支撐了整個電商網站,現在對整個網站進行拆解,分離出了訂單中心、用戶中心、庫存中心等,對於訂單中心,有專門的資料庫存儲訂單信息,用戶中心也有專門的資料庫存儲用戶信息,庫存中心也會有專門的資料庫存儲庫存信息,如果要同時對訂單和庫存進行操作,那麼就會涉及到訂單資料庫和庫存資料庫,為了保證數據一致性,就需要用到分布式事務。
分布式事務:分布式事務就是指事務的參與者、支持事務的伺服器、資源伺服器以及事務管理器分別位於不同的分布式系統的不同節點之上。簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分布在不同的伺服器上,且屬於不同的應用,分布式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分布式事務就是為了保證不同資料庫的數據一致性。
最早的分布式事務應用架構不涉及服務之間的訪問調用,僅僅是服務內操作涉及對多個資料庫資源的訪問。
當一個服務操作訪問不同的資料庫資源,又希望對它們的訪問具有事務特性時,就需要採用分布式事務來協調所有的事務參與者。
在上面的分布式事務應用架構中,儘管一個服務操作會訪問多個資料庫資源,但是畢竟整個事務還是控制在單一服務的內部。如果一個服務操作需要調用另外一個服務,這時的事務就需要跨越多個服務了。在這種情況下,起始於某個服務的事務在調用另外一個服務的時候,需要以某種機制流轉到另外一個服務,從而使被調用的服務訪問的資源也自動加入到該事務當中來。下圖反映了這樣一個跨越多個服務的分布式事務:
如果將上面這兩種場景(一個服務可以調用多個資料庫資源,也可以調用其他服務)結合在一起,對此進行延伸,整個分布式事務的參與者將會組成如下圖所示的樹形拓撲結構。在一個跨服務的分布式事務中,事務的發起者和提交均系同一個,它可以是整個調用的客戶端,也可以是客戶端最先調用的那個服務。
分布式事務是最核心的還是其ACID特性。研究分布式事務本質上還是研究其是如何保證ACID的。事務模型為分布式事務提供了理論基礎,像2PC、3PC協議則是實現分布式事務的設計方案。
DTP模型( X/Open Distributed Transaction):最早的分布式事務模型,是由 X/Open 國際聯盟提出的,也就是X/Open XA協議,簡稱XA協議。
DTP模型包含一個全局事務管理器(TM Transaction Manager)和多個資源管理器(RM Resource Manager)。全局事務管理器負責管理全局事務狀態與參與的資源,協同資源一起提交或回滾;資源管理器負責具體的資源操作。
XA協議描述了TM與RM之間的接口,允許多個資源在同一分布式事務中訪問。
TM:Transaction Manager 事務管理器
RM:Resource Manager 資源管理器
基於 DTP 模型的分布式事務流程大致如下:
1、原子性
XA協議使用2PC(Two Phase Commit 兩階段提交)原子提交協議來保證分布式事務原子性。
兩階段提交是指將提交過程分為兩個階段:準備階段(投票階段)和提交階段(執行階段)。
存在的問題:
同步阻塞:當參與事務者存在佔用公共資源的情況,其中一個佔用了資源,其他事務參與者就只能阻塞等待資源釋放,處於阻塞狀態。並發性差。
單點故障:一旦事務管理器出現故障,整個系統不可用
數據不一致:在階段二,如果事務管理器只發送了部分 commit 消息,此時網絡發生異常,那麼只有部分參與者接收到 commit 消息,也就是說只有部分參與者提交了事務,使得系統數據不一致。
2、隔離性
XA 協議中沒有描述如何實現分布式事務的隔離性,但是 XA 協議要求 DTP 模型中的每個 RM 都要實現本地事務,也就是說,基於 XA 協議實現的分布式事務的隔離性是由每個 RM 本地事務的隔離性來保證的,當一個分布式事務的所有子事務都是隔離的,那麼這個分布式事務天然的就實現了隔離性。
以 MySQL 來舉例,MySQL 使用 2PL(Two-Phase Locking,兩階段鎖)機制來控制本地事務的並發,保證隔離性。2PL 與 2PC 類似,也是將鎖操作分為加鎖和解鎖兩個階段,並且保證兩個階段完全不相交。加鎖階段,只加鎖,不放鎖。解鎖階段,只放鎖,不加鎖。
如上圖所示,在一個本地事務中,每執行一條更新操作之前,都會先獲取對應的鎖資源,只有獲取鎖資源成功才會執行該操作,並且一旦獲取了鎖資源就會持有該鎖資源直到本事務執行結束。
MySQL 通過這種 2PL 機制,可以保證在本地事務執行過程中,其他並發事務不能操作相同資源,從而實現了事務隔離。
3、一致性
前面提到一致性有兩層語義,一層是確保事務執行結束後,資料庫從一個一致狀態轉變為另一個一致狀態。另一層語義是事務執行過程中的中間狀態不能被觀察到。
TCC(Try-Confirm-Cancel)分布式事務模型相對於 XA 等傳統模型,其特徵在於它不依賴資源管理器(RM)對分布式事務的支持,而是通過對業務邏輯的分解來實現分布式事務。
TCC 模型認為對於業務系統中一個特定的業務邏輯,其對外提供服務時,必須接受一些不確定性,即對業務邏輯初步操作的調用僅是一個臨時性操作,調用它的主業務服務保留了後續的取消權。如果主業務服務認為全局事務應該回滾,它會要求取消之前的臨時性操作,這就對應從業務服務的取消操作。而當主業務服務認為全局事務應該提交時,它會放棄之前臨時性操作的取消權,這對應從業務服務的確認操作。每一個初步操作,最終都會被確認或取消。
TCC事務機制相比於上面介紹的XA,解決了其幾個缺點:
MySQL 的 InnoDB 引擎其實能夠支持分布式事務,也就是我們經常說的 XA 事務;XA 事務就是用了我們在上一節中提到的兩階段提交協議實現分布式事務,其中事務管理器為協調者,而資源管理器就是分布式事務的參與者