1. 程式人生 > >關於利用MQ實現分散式事務的想法【轉】

關於利用MQ實現分散式事務的想法【轉】

轉自:https://www.jianshu.com/p/bafb09954f18

 

假設:訊息服務不丟訊息

場景 服務A 服務B 服務C 訊息服務Q

虛擬碼

服務A中
transaction{
A本地事務
B.callB();
C.callC();
A本地事務
}

利用訊息服務來實現分散式事務
原理 當服務A執行事務時,所有指定遠端呼叫會被轉換為傳送一條呼叫訊息到訊息服務,當B和C接收到訊息時,立即執行訊息指定的方法,並在提交前傳送回覆訊息給A(攜帶有返回值)並且等待接收提交或者回滾訊息,服務A執行完方法也在提交前等待B和C的回覆,當B和C的回覆都為sucess時傳送提交訊息給B和C,然後自己提交,否則回滾。B和C接到提交訊息後,提交,否則回滾。

異常情況一:在傳送呼叫B的訊息時失敗
服務A事務直接回滾

異常情況二:在傳送呼叫C的訊息時失敗
服務A事務直接回滾,併發送回滾訊息到指定佇列(此兩步操作由Q的事務訊息保證原子性)

異常情況三:服務A提交和回滾失敗
由於服務A提交和回滾操作和傳送提交或者回滾訊息在一個事務內,所以放在一起討論,
由於此部分由訊息中介軟體保證原子性,固提交或者回滾失敗,不會有提交或者回滾訊息到達訊息中介軟體,B和C等待一段時間後自動回滾

異常情況四:B在傳送回覆訊息時失敗
A在等待指定時間後沒有收到B的回覆,進行回滾操作併發送回滾訊息到指定佇列,C在收到回滾訊息後回滾,B在等待指定時間後沒有收到A的提交訊息回滾

異常情況五:C在傳送回覆訊息時失敗
同異常情況四

異常情況六:B提交失敗或者C提交失敗
B或C中呼叫訊息和提交訊息均不消費,會進行重試

異常情況七:B或者C回滾失敗
同異常情況六

異常情況八:B或者C邏輯出現異常導致失敗
B或者C直接回滾,並且傳送失敗回覆

停機啟動恢復處理

由於異常導致的宕機,然後重啟後的邏輯

一、只接收到呼叫訊息,執行,然後等待固定時間後回滾。
二、按照順序接收到呼叫訊息和提交訊息,執行然後提交
三、先接收到提交訊息後接收到呼叫訊息,一樣,執行然後提交
四、接收到呼叫和回滾訊息,同上

從上可以推匯出,利用訊息系統做分散式事務的兩個特性
強調一下假設:訊息服務不丟訊息
一、在網路暢通所有服務高可用的情況下,可以做到資料的強一致性
二、在網路和服務可能存在故障的情況下,可以做到資料的最終一致性

關於資料在最終一致性情況下的查詢問題
1.最好的解決方案是不管,更新後查詢資料查到舊的資料就讓它查到舊的資料
2.可以利用快取,自己寫邏輯實現,還未提交的資料快取下來,查詢時先查詢快取