用戶創(chuàng)建訂單的時(shí)候,因?yàn)橹貜?fù)點(diǎn)擊(前端bug)或者網(wǎng)絡(luò)超時(shí)重傳等原因豪诲,會(huì)導(dǎo)致重復(fù)請(qǐng)求蒿讥,那么系統(tǒng)如何即使有重復(fù)請(qǐng)求也不會(huì)重復(fù)下單呢,也就是如何實(shí)現(xiàn)冪等性
冪等性
- 多次請(qǐng)求的效果跟一次請(qǐng)求的效果一樣
實(shí)現(xiàn)方式
實(shí)現(xiàn)冪等性一般需要前后端聯(lián)合實(shí)現(xiàn)
前端
- 前端請(qǐng)求的時(shí)候需要攜帶一個(gè)唯一ID: 后臺(tái)會(huì)使用該唯一ID進(jìn)行冪等判斷
- 前端按鈕點(diǎn)擊后友绝,需要置灰: 減少重復(fù)請(qǐng)求次數(shù)
- 前端進(jìn)入提交頁后就生成唯一ID堤尾,而不是每次點(diǎn)擊按鈕時(shí)生成
唯一ID: 生成這個(gè)唯一ID的來源,可以是后臺(tái)迁客,這樣可以保證唯一郭宝,如果是前端生成的話一般很難保證。不過這個(gè)ID只是為了實(shí)現(xiàn)冪等性掷漱,對(duì)唯一性要求并沒有那么嚴(yán)格粘室,能夠保證一天唯一就已經(jīng)滿足要求了。畢竟隔了一天時(shí)間卜范,不可能還是重復(fù)請(qǐng)求了
后臺(tái)
- 后臺(tái)可以處理請(qǐng)求時(shí)衔统,首先判斷redis中是否已經(jīng)存在該ID,如果存在,則說明重復(fù)請(qǐng)求锦爵,就可以返回創(chuàng)建成功舱殿;如果不存在,則在redis創(chuàng)建一個(gè)key险掀,并設(shè)置過期時(shí)間為一天
- 有的方案使用數(shù)據(jù)庫的唯一鍵來保證冪等性沪袭,因?yàn)樾碌挠唵尾迦胧。沁@個(gè)方案有兩個(gè)缺點(diǎn):一是需要由后臺(tái)生成唯一ID樟氢;二是創(chuàng)建訂單的時(shí)候冈绊,一般會(huì)先完成促銷扣減,庫存扣減等操作埠啃,然后再插入數(shù)據(jù)庫死宣,這樣的話遇到重復(fù)請(qǐng)求,處理得代價(jià)就比較高
優(yōu)化
- 就算ID不一樣碴开,如果訂單信息完全一樣十电,也需要提醒用戶是否重復(fù)下單