<i id="bcuty"><sub id="bcuty"></sub></i>

<b id="bcuty"></b>

您的位置:首頁 >聚焦 >

創建訂單和更新訂單的數據一致性問題

2023-02-25 15:37:10    來源:程序員客棧

大家好,我是Leo。

聊一下創建訂單和更新訂單的數據一致性問題,文章分類主要是MySQL,Redis,秒殺系統,RocketMQ,計算機網絡,大廠面試,設計模式,Nginx。先整理一下。方便粉絲更好的閱讀,同時也方便自己不斷的復習沉淀。

重復下單

我們在下單時,往往會因為網絡問題出現多次下單的情況,比如點了下單一直沒反應,我們就會多次的重復點擊,如果服務端做了校驗可能不會出現什么問題,如果沒做的話在訂單列表里可能就會出現多個訂單。


【資料圖】

解決方案就是我們可以對訂單實現具備冪等性。

冪等性就是無論點擊多少次下單,始終只會創建一條記錄。

如果系統體量比較大的話,我們可以獨立一個生成訂單號服務,體量不大的話可以封裝成一個API給訂單服務使用。

當用戶從購物車界面點結算挑戰到訂單詳情界面就請求一次生成訂單號,使這個訂單詳情頁的緩存中保存一條唯一的訂單號只要每次下單請求的訂單號是唯一的,我們再借助數據庫中主鍵唯一約束性來實現,訂單數據的唯一性。

如果主鍵是訂單號的話,主鍵自動幫我們實現了。如果主鍵是時間戳ID的話,我們把訂單號字段設為唯一索引,同時也可以避免重復下單的校驗需求。

ABA問題

訂單服務會經常出現ABA問題。

什么是 ABA 問題呢?我們舉個例子,訂單支付之后,小二要發貨,發貨完成后要填個快遞單號。假如小二填了一個單號 666,剛填完,發現填錯了,趕緊再修改成 888。對訂單服務來說,這就是 2 個更新訂單的請求。

正常情況下,訂單中的快遞單號會先更新成 666,再更新成 888,這是沒問題的。那不正常情況呢?666 請求到了,單號更新成 666,然后 888 請求到了,單號又更新成 888,但是 666 更新成功的響應丟了,調用方沒收到成功響應,自動重試,再次發起 666 請求,單號又被更新成 666 了,這數據顯然就錯了。這就是ABA 問題。

解決方案就是我們在訂單表中加一個版本號這個字段。

在查詢訂單時,我們可以把版本號返回給前端,前端在處理下單時,以參數的形式傳遞給后端,后端收到版本號之后與數據庫的實際數據對比,如果版本號符合,修改數據,版本號遞增。

為了考慮數據安全性,我們一般會將 校驗版本號,修改數據,修改版本號在一個事務中執行

UPDATE orders set tracking_number = 666, version = version + 1WHERE version = 8;

通過版本號,我們就可以得知,在每次修改數據時,是否有其他人修改過。這樣就不會出現ABA問題了。

關鍵詞: 數據一致性 解決方案 快遞單號

相關閱讀

巨胸护士在线播放视频二区

<i id="bcuty"><sub id="bcuty"></sub></i>

<b id="bcuty"></b>