引言
本文主要介紹java中分布式事務以及對應的解決方案。
分布式事務產生的原因
數據庫分庫分表
當數據庫單表一年產生的數據超過1000W,那么就要考慮分庫分表,具體分庫分表的原理在此不做解釋,以后有空詳細說,簡單的說就是原來的一個數據庫變成了多個數據庫。這時候,如果一個操作既訪問01庫,又訪問02庫,而且要保證數據的一致性,那么就要用到分布式事務。
SOA優化
所謂的SOA化,就是業務的服務化。比如原來單機支撐了整個電商網站,現在對整個網站進行拆解,分離出了訂單中心、用戶中心、庫存中心。對於訂單中心,有專門的數據庫存儲訂單信息,用戶中心也有專門的數據庫存儲用戶信息,庫存中心也會有專門的數據庫存儲庫存信息。這時候如果要同時對訂單和庫存進行操作,那么就會涉及到訂單數據庫和庫存數據庫,為了保證數據一致性,就需要用到分布式事務。
事務的特性
1. 原子性:在整個事務中的所有操作,要么全部完成,要么全部不做,沒有中間狀態。對於事務在執行中發生錯誤,所有的操作都會被回滾,整個事務就像從沒被執行過一樣。
2. 一致性:事務的執行必須保證系統的一致性,就拿轉賬為例,A有500元,B有300元,如果在一個事務里A成功轉給B50元,那么不管並發多少,不管發生什么,只要事務執行成功了,那么最后A賬戶一定是450元,B賬戶一定是350元。
3. 隔離性:所謂的隔離性就是說,事務與事務之間不會互相影響,一個事務的中間狀態不會被其他事務感知。
4. 持久性:所謂的持久性,就是說一單事務完成了,那么事務對數據所做的變更就完全保存在了數據庫中,即使發生停電,系統宕機也是如此。
分布式事務的應用場景
支付
最經典的場景就是支付了,一筆支付,是對買家賬戶進行扣款,同時對賣家賬戶進行加錢,這些操作必須在一個事務里執行,要么全部成功,要么全部失敗。而對於買家賬戶屬於買家中心,對應的是買家數據庫,而賣家賬戶屬於賣家中心,對應的是賣家數據庫,對不同數據庫的操作必然需要引入分布式事務。
在線下單
買家在電商平台下單,往往會涉及到兩個動作,一個是扣庫存,第二個是更新訂單狀態,庫存和訂單一般屬於不同的數據庫,需要使用分布式事務保證數據一致性。
實現方式
通過在應用層面來解決:保持多個數據庫連接,用一個連接的列表,不提交/提交的的話同時提交,否則一起回滾。
Spring 事務管理接口
基於事務管理器和本地資源管理器的兩階段提交
XA中大致分為兩部分:事務管理器和本地資源管理器。其中本地資源管理器往往由數據庫實現,比如Oracle、DB2這些商業數據庫都實現了XA接口,而事務管理器作為全局的調度者,負責各個本地資源的提交和回滾。
消息事務+最終一致性
所謂的消息事務就是基於消息中間件的兩階段提交,本質上是對消息中間件的一種特殊利用,它是將本地事務和發消息放在了一個分布式事務里,保證要么本地操作成功成功並且對外發消息成功,要么兩者都失敗。
TCC 編程模式
所謂的TCC編程模式,也是兩階段提交的一個變種。TCC提供了一個編程框架,將整個業務邏輯分為三塊:Try、Confirm和Cancel三個操作。以在線下單為例,Try階段會去扣庫存,Confirm階段則是去更新訂單狀態,如果更新訂單失敗,則進入Cancel階段,會去恢復庫存。