最近遇到的問題,之前沒有怎么注意,前端APP用異步提交訂單,訂單需要扣減余額,類似于快速下單秒殺的這種,用戶可能在1秒內(nèi)下單5次左右。一般的邏輯寫法是:
APP用戶提交訂單金額,邏輯處理后,查詢余額,余額>訂單金額,提交成功并扣除賬戶余額,記錄流水。
同步的時候這種情況是沒錯的,但是在異步的時候,用戶一秒內(nèi)下單5,6次,用戶余額10元,每次下單3元,
1秒5次的情況下,會導(dǎo)致余額變成負(fù)數(shù),第1次訂單余額是10元,這個時候訂單可能還沒有扣除余額,第2次就提交上來了,又是查到10元,依次的情況下,負(fù)數(shù)就出現(xiàn)了。。
請教下,如何保證前端APP異步提交的情況下,余額等賬戶情況保持一致性,不會出現(xiàn)這種金額負(fù)數(shù)的情況呢?
沒有這方面的經(jīng)驗,但接手項目,頭疼~~
兩方面來的吧;
後端:如果不支持餘額為負(fù)數(shù)的情況,下單->扣款->返回結(jié)果 應(yīng)當(dāng)是一個事務(wù),執(zhí)行後餘額不等於0或庫存充足的情況下才提交事務(wù);
前端:如果禁止重複下單,下單後按鈕disable,有結(jié)果後才enable?;蛘咄ㄟ^節(jié)流防抖那套方案。
正解,如果要防止數(shù)據(jù)庫壓力過大,可以執(zhí)行 數(shù)據(jù)庫事務(wù)之前,加上redis鎖,就最簡單的那種就行了,事務(wù)提交成功了刪除key,不然再下單,就直接返回失敗
可以執(zhí)行 數(shù)據(jù)庫事務(wù)之前,加上redis鎖,用戶的錢包余額,沒地進(jìn)redis的,因為需要實時更新這塊,我直接都是從數(shù)據(jù)庫里面實時取出來的。如果redis如何保證用戶的余額與redis里面的是一致的?
“按鈕如果disable用戶體驗就差了”;其實看你怎樣設(shè)計,如提交時異步的,disable按鈕後害怕體驗差,那就加上搶購中的動畫效果;但始終需要分開,前端的disable是為了防止重複提交對後端產(chǎn)生額外的性能開銷和流量開銷,並不是為了防止重單;重單的應(yīng)該後端事務(wù)控制;而如果你是搶購類的,其實還不如預(yù)熱的時候把數(shù)據(jù)丟入redis,redis進(jìn)行庫存控制,數(shù)據(jù)延遲入庫,這樣就能避免數(shù)據(jù)庫壓力
這個插件非常適合你,支持文件鎖,redis鎖等各種