在單體應用中藉助數據庫的事物我們可以很方便的實現數據的一致性。
但是當單體應用被拆分成不同的服務時候,所有服務是分開部署到不用的機器上,所以無法通過單純的事物保證數據的一致性。
而且因爲跨服務的調用(rpc 或者 restful)可能以爲網絡的原因導致服務調用失敗。
服務調用失敗可以分爲
1.服務提供方掛了,無法提供服務
2.服務提供方 執行程序時候異常
3.服務提供方成功執行了服務,因爲網絡原因導致調用方沒有收到success
藉助於電商系統 生成訂單 鎖定庫存的場景來分析
系統分爲 訂單服務 和 庫存服務。
當用戶下單時候
調用訂單服務生成訂單,訂單服務再調用庫存服務鎖定庫存。
正常流程
1 訂單生成成功,庫存被鎖定。
2 訂單生成失敗,影響不大,用戶重新調用生成訂單
3 訂單生成成功,鎖定庫存失敗,訂單回滾,也ok
不一致情況
下單成功,庫存服務鎖定庫存成功,但是因爲網絡原因,沒有返回給訂單服務success ,導致訂單回滾。
即訂單生成失敗,庫存卻被鎖定了。對於商家來說就是明明有商品卻無法賣出去。
這種情況,的解決辦法:
1 分佈式事物,但是比較複雜,影響系統性能。
2 通過補償操作來達到最終一致性。
這裏給大家介紹下補償操作來實現最終一致性
商家通過後臺查看出庫記錄,發現有的鎖定庫存操作關聯了無效的訂單,就知道是異常訂單了。
然後通過撤銷動作,來釋放庫存,來保證庫存的正確性。
我這裏爲了簡單,通過了人去觸發錯誤的補償。
也可以通過程序自動的實現補償操作。
1.訂單報異常時候 將訂單id 保存到消息隊列中
2 讀取異常訂單消息 ,釋放關聯了無效訂單的庫存