補充上個帖子的分布式事務之扣減庫存

2021-10-24 15:21:50 字數 1319 閱讀 9297

當業務規模不大,並且對於生成訂單並凍結庫存等操作要求一致性較高時,比較推薦acid資料庫進行操作,加入快取或訊息佇列後複雜度以及實時一致性較差;

比如有如下場景:

步驟相關業務

1凍結庫存(保證下單時有足夠的庫存)

2生成對應的訂單

3支付訂單,扣減凍結庫存

(1)該場景如果僅使用acid資料庫進行控制,則偽**為:

@transactional(rollbackfor = exception.class)

public result placeorder(*** ***)

//進行訂單生成等其他業務操作;

}

以上**能夠應付一般的併發下單了,但是如果涉及到下單有多個商品,在扣除庫存前有其他事務(例如需要扣除積分,但是積分操作只涉及使用者個人),那麼整個方法將是乙個大事務,相關的庫存行鎖將占用時間較長,影響了其他使用者的下單;

(2)根據以上問題,優化一下,將扣除庫存及生成訂單的操作提取出來,並且使用requires_new事務傳播型別,旨在完成凍結庫存成功後,結束當前事務操作,進行後續耗時操作;

@transactional(rollbackfor = exception.class)

public result placeorder(*** ***)

}

(3)其實在凍結庫存時可能還會出現個問題,就是可能會出現mysql的迴圈占用資源死鎖的問題,具體相關概念可以去其他地方查詢,我這裡給出的最簡單的方法就是將用於扣減庫存的商品列表,使用某一字段進行排序避免;此方式同樣適用於排程任務在處理批量回滾商品庫存等業務中;

(4)比如我們想在該下單方式的基礎上,支援rpc呼叫,例如商品是單獨服務,訂單又是單獨服務,如何保證一致性:

@transactional(rollbackfor = exception.class)

public result placeorder(*** ***)

//進行訂單生成等其他業務操作;

boolean b = rpc.createorder(***);

//生成訂單業務包括:生成訂單,刪除凍結庫存日誌;

}task:根據生成時間等條件查詢凍結庫存日誌,進行回滾;

以上方式,可能會存在下單失敗,但是暫時將庫存扣除的問題,這就要合理的規劃排程回滾庫存以及根據具體業務場景選擇下單方式;

(5)其他的下單方式,例如:

1)在付款時在進行扣減庫存,判斷是否可以支付;

2)不在意庫存扣為負數,或者有其他方式避免庫存不足,不需要判斷庫存,則直接可以下單成功使用訊息佇列等方式,進行最終一致性的重試;

tcc分布式事務 分布式事務之TCC事務模型

我們先套乙個業務場景進去,如下圖所示 那頁面點了支付按鈕,呼叫支付服務,那我們後台要實現下面三個步驟 1 訂單服務 修改訂單狀態 2 賬戶服務 扣減金錢 3 庫存服務 扣減庫存 達到事務的效果,要麼一起成功,要麼一起失敗!就要採取tcc分布式事務方案!tcc的全稱是 try confirm canc...

分布式事務 分布式事務的實現

如果在多個服務中需要對不同的資料庫進行操作。因為不同服務操作的資料庫都不同,所以保證在同乙個事務中完成操作顯然是不科學的。那實現分布式事務的思想 1 方法入口,建立一條日誌記錄,狀態定義為初始狀態,即儲存本條日誌記錄 可以儲存在資料庫中,也可以寫出到本地磁碟檔案 2 可以在非同步執行緒或在定時任務中...

分布式事務之TCC

假設現在有乙個電商系統,裡面有乙個支付訂單的場景。對乙個訂單進行支付之後,我們需要做下面的步驟 以上業務場景對應下面的 public class orderservice tcc是try confirm cancel的簡稱 try 階段 嘗試執行,完成所有業務檢查 一致性 預留必需業務資源 準隔離性...