一、什麼是分散式事務 在早期的單體架構時期,所有的數據操作都在同一個資料庫裡面進行,比如:A給B轉100塊錢,A的賬戶餘額-100,B的賬戶餘額+100,這兩個操作放在同一個事務裡面即可,由資料庫來保證事務的原子性、一致性、持久性、隔離性。但是隨著業務量、數據量的加大,放在一個資料庫裡面很難支撐,所 ...
一、什麼是分散式事務
在早期的單體架構時期,所有的數據操作都在同一個資料庫裡面進行,比如:A給B轉100塊錢,A的賬戶餘額-100,B的賬戶餘額+100,這兩個操作放在同一個事務裡面即可,由資料庫來保證事務的原子性、一致性、持久性、隔離性。但是隨著業務量、數據量的加大,放在一個資料庫裡面很難支撐,所以需要對資料庫按照業務來進行拆分,比如積分兌換商品下單操作涉及如下操作:
1.用戶積分扣減(積分資料庫)
2.商品庫存扣減(商品庫存資料庫)
3.訂單創建(訂單資料庫)
這三個操作在三個不同的資料庫裡面進行,這樣就導致傳統的資料庫事務不能保證這三個操作的原子性了,於是就需要分散式事務來處理這類問題。
二、常見的分散式事務解決方案有哪些?
1.兩階段提交協議
由事務協調者和事務參與者構成,把分散式事務分成兩個階段:
一階段:事務協調者調用各個事務參與者進行資源準備,這個階段各個參與者會執行本地事務,進入prepare階段,但是本地事務不會提交;
二階段:事務協調者根據調用結果,來決定第二階段是執行commit還是rollback操作,如果一階段中只要有一個參與者返回失敗,就執行rollback操作,只有當所有參與者都返回成功時才執行commit操作。
兩階段協議有什麼缺點呢?
(1)性能較差:因為會阻塞性的鎖定資料庫資源,如果其中某個參與者執行很慢,其它的參與者也需要等著;
(2)可能導致數據不一致:如果參與者和協調者都掛了;
(3)可靠性較差:協調者存在單點故障的問題,如果出現故障,參與者就會一直處於阻塞狀態。
2.三階段提交協議
在兩階段提交的基礎上多加了一個階段:先問一下每個參與者是否可以提交事務,如果可以就會進入第二階段,這個階段會鎖定資料庫資源,後面兩個階段在兩階段協議的基礎上增加了參與者如果等待協調者超時,可以直接提交事務的處理。
三階段的優點:如果協調者出現問題,參與者不會一直阻塞;
缺點:沒有解決數據一致性的問題,在第三階段如果協調者出現問題時可能導致數據不一致。
3.TCC
一階段為try,二階段為confirm或者cancel;2PC和3PC都是資料庫層面的,而 TCC 是業務層面的分散式事務,就像我前面說的分散式事務不僅僅包括資料庫的操作,還包括發送簡訊等,這時候 TCC 就派上用場了!
TCC屬於補償型事務,一階段會先預留資源,如果成功則確認,否則補償退回就行。
TCC最大的缺點就是需要自己實現try、confirm、cancel三個方法,對業務侵入性較大,實現起來也會比較麻煩。使用TCC要註意一下幾個問題:
(1)空回滾:如果try還沒執行,cancel方法就執行了,這個時候沒有資源可以補償,需要允許這種case發生,直接發揮成功就好;
(2)防懸掛:上面說到了允許空回滾的發生,那try方法可能後面又會執行,如果不處理,會導致資源會鎖住了,並且不會釋放;
(3)冪等:confirm、cancel方法需要考慮網路等問題導致的執行失敗,需要重試的問題。
4.本地事務表
缺點:需要增加本地消息表,對業務侵入較大。
5.事務性消息
不是所有的消息中間件都支持,目前主流的只有rocketMq支持,同時對業務也有一定的侵入。與TCC相比,二者使用的場景不太一樣,TCC一階段就會鎖定所有資源,如果失敗瞭解除資源鎖定就好了,但是事務性消息並沒有鎖定所有資源,生產者發送成功了,通過重試的方式保證消費者也能消費成功,如果消費不成功需要告警然後人工介入處理。