分佈式事務,常見的兩個處理辦法就是兩段式提交和補償。
兩段式提交典型的就是XA,有個事務協調器,告訴你們,來都準備好提交,你們回覆,都準備好了,而後協調器告訴你們,一塊兒提交,你們都提交了。
補償比較好理解,先處理業務,而後定時或者回調裏,檢查狀態是否是一致的,若是不一致採用某個策略,強制狀態到某個結束狀態(通常是失敗狀態),而後就世界太平了。典型的就是衝正操做。
準備好了之後,若是沒有問題,收到提交,全部人都開始提交。
這個時候,好比對數據庫來講,有redo日誌的。
若是某個數據庫這時候宕機了,那麼它重啓的時候,先執行檢查,也會把上一次的這些操做都提交掉的。因此各個點的數據都是一致的。
問題 1:好比 一個業務要調用不少的服務都是寫操做,若是有其中一個寫的服務失敗了,怎麼辦 ?假設 4個寫的吧,有2個寫失敗了 。
kimmking:淘寶之類的網站通常的作法是,若是4個都成功纔算成功,那麼此次提交時4個寫都設置成一箇中間狀態,先允許不一致。而後4個執行完成了之後,回調或是定時任務裏檢查這4個數據是否是一致的,若是一致就所有置爲成功狀態,若是不一致就所有置爲失敗。
複雜的業務交互過程當中,不建議使用強一致性的分佈式事務。解決分佈式事務的最好辦法就是不考慮分佈式事務。就像剛說的問題同樣,把分佈式的事務過程拆解成多箇中間狀態,中間狀態的東西不容許用戶直接操做,等狀態都一致成功,或者檢測到不一致的時候所有失敗掉。就解耦了這個強一致性的過程。
通常狀況下準實時就成了。涉及到錢,有時候也能夠這麼搞。
淘寶幾s內完整一個訂單處理,不是什麼問題吧。
銀行也不是所有都強一致性。也會扎差,也會衝正。
特別是涉及到多個系統的時候,咱們好比買機票,支付完成之後,只支付完成狀態,而後返回給用戶了,咱們過幾分鐘再刷新頁面,纔會看到變成已出票,訂單完成狀態。
這個時候,若是咱們要求全部處理,都是強一致性的,那麼久完蛋了。頁面要死在那兒幾分鐘,才把這個事務處理完成,返回給用戶。
這樣就確定涉及一個問題,支付了,可是最終出票沒出來。那就沒辦法,商量換票或退款。
淘寶的訂單改爲出票失敗,給支付發消息通知退款。
慢的時候,有多是手工出票,這時出一張票半小時均可能,若是要求都必須強一致性的話,全部處理線程都掛在哪兒,系統早就完蛋了。
解決分佈式事務的最好辦法就是不考慮分佈式事務。
拆分,大的業務流程,轉化成幾個小的業務流程,而後考慮最終一致性。
問題2:分佈式事務是大家本身開發的,仍是數據庫自帶的?
kimmking:
一、只要一個處理邏輯能保證要麼成功,要麼跟什麼也沒作同樣,都算是事務。數據庫事務,MQ也有事務。
你本身甚至能夠寫個程序生成兩個文件,要麼都生成了,要麼都刪掉不留痕跡,這也算是事務。
二、分佈式事務這一塊有個XA規範,實現XA接口的事務,均可以加入到一個分佈式事務中,被XA容器管理起來。
三、補償的辦法,須要具體狀況具體分析,沒有一個各類場合都適用的框架。