如何防止接口重復(fù)提交?
一、摘要
對于投入運營的軟件系統(tǒng),最近小編在巡檢項目數(shù)據(jù)庫的時候,發(fā)現(xiàn)某些表存在不少的重復(fù)數(shù)據(jù),對于這樣的臟數(shù)據(jù),初步分析大致的來源有以下可能:
1.由于用戶誤操作,多次點擊表單提交按鈕
2.由于網(wǎng)速等原因造成頁面卡頓,用戶重復(fù)刷新提交頁面
3.黑客或惡意用戶使用 postman 等網(wǎng)絡(luò)工具,重復(fù)惡意提交表單
這些情況都可能會導(dǎo)致表單重復(fù)提交,造成數(shù)據(jù)重復(fù),比如訂單表,重復(fù)提交訂單數(shù)據(jù)所造成的問題,可能不僅僅是數(shù)據(jù)上的混亂,也會造成業(yè)務(wù)混亂。
那么問題來了,我們該如何防止用戶重復(fù)提交數(shù)據(jù)呢?
方案實踐如下!
二、方案實踐
下面我們以防止重復(fù)提交訂單為例,向大家介紹最簡單的、成本最低的解決辦法。
我們先來看一張圖,這張圖就是本次方案的核心流程圖。
實現(xiàn)的邏輯,流程如下:
1.當(dāng)用戶進(jìn)入訂單提交界面的時候,調(diào)用后端獲取請求唯一ID,并將唯一ID值埋點在頁面里面
2.當(dāng)用戶點擊提交按鈕時,后端檢查這個唯一ID是否用過,如果沒有用過,繼續(xù)后續(xù)邏輯;如果用過,就提示重復(fù)提交
3.最關(guān)鍵的一步操作,就是把這個唯一ID 存入業(yè)務(wù)表中,同時設(shè)置這個字段為唯一索引類型,從數(shù)據(jù)庫層面做防止重復(fù)提交
防止重復(fù)提交的大體思路如上,實踐代碼如下!
2.1、給數(shù)據(jù)庫表增加唯一鍵約束
以訂單表為例,新增一個request_id字段,并設(shè)置為唯一約束,結(jié)構(gòu)如下:
2.2、編寫獲取請求唯一ID的接口
2.3、業(yè)務(wù)提交的時候,檢查唯一ID
如果是并發(fā)請求也不用擔(dān)心,因為數(shù)據(jù)庫表已經(jīng)設(shè)置了唯一索引,尤其只有一條有效數(shù)據(jù)會插入成功,可以防止重復(fù)的數(shù)據(jù)產(chǎn)生。
三、小結(jié)
對于下單流量不算高的系統(tǒng),可以采用這種請求唯一ID+數(shù)據(jù)表增加唯一索引約束的方式,來防止接口重復(fù)提交!
雖然簡單粗暴,但是十分有效!
可能有的人會問,看上面的代碼生成請求唯一 ID 很簡單,為啥不直接前端生成一個請求唯一ID,然后提交呢?
之所以把獲取請求唯一ID的生成規(guī)則放在后端,好處就是生成規(guī)則可以自己定義,也并不一定要用uuid來生成,也可以用雪花算法,或者自己設(shè)計一套計算規(guī)則,保證當(dāng)前業(yè)務(wù)提交時請求ID是唯一的,比如事先生成唯一的訂單號,作為請求唯一ID,然后再提交,規(guī)則放在后端來生成,會更加靈活!