新聞中心
本文轉載自微信公眾號「UP技術控」,作者 conan5566。轉載本文請聯(lián)系UP技術控公眾號。 conan5566

成都創(chuàng)新互聯(lián)公司作為成都網(wǎng)站建設公司,專注重慶網(wǎng)站建設公司、網(wǎng)站設計,有關成都定制網(wǎng)站方案、改版、費用等問題,行業(yè)涉及崗亭等多個領域,已為上千家企業(yè)服務,得到了客戶的尊重與認可。
背景
在平常開發(fā)中,我們經常會面對防止重復請求的問題。當服務端對于請求的響應涉及數(shù)據(jù)的修改,或狀態(tài)的變更時,可能會造成極大的危害。重復請求的后果在交易系統(tǒng)、售后維權,以及支付系統(tǒng)中尤其嚴重。但是很多時候,都是指望著前端來限制,比如提交之后,按鈕diseabled之類的,其實這些都是不靠譜的。關鍵時候還是需要后端來校驗。
解決方式
1、基于緩存數(shù)據(jù)狀態(tài)的驗證
Redis存儲查詢輕量快速。在request進來的時候,可以先記錄在緩存中。后續(xù)進來的request每次進行驗證。整個流程處理完成,清除緩存。
- if (!CacheExtension.getInstance().AddUnique($"{key}_unique", 1, DateTimeOffset.Now.AddDays(365)))
- {
- LogExtention.getInstance().WriteCustomLogAsync("", "", true, "上批次還未執(zhí)行結束");
- return ResponseResult.FromError("上批次還未執(zhí)行結束!");
- }
- if (!string.IsNullOrEmpty(uniqueKey))
- {
- CacheExtension.getInstance().Remove(uniqueKey);
- }
- return ResponseResult.Ok();
2、利用唯一索引機制的驗證
需要原子性操作,想到了數(shù)據(jù)庫的唯一索引。新建一個表,每次request進來則往表里面插入數(shù)據(jù), 操作完成后,刪除此條記錄。
3、基于緩存的計數(shù)器驗證
由于數(shù)據(jù)庫的操作比較消耗性能,了解到redis的計數(shù)器也是原子性操作。果斷采用計數(shù)器。既可以提高性能,還不用存儲,而且能提升qps的峰值。 每次request進來則新建一個以orderId為key的計數(shù)器,然后+1。如果>1(不能獲得鎖): 說明有操作在進行,刪除。如果=1(獲得鎖): 可以操作。
- redis> SET test 20
- OK
- redis> INCR test
- (integer) 21
- redis> GET test # 數(shù)字值在 Redis 中以字符串的形式保存
- "21"
- //獲取指定的所有計數(shù)器
- HGETALL counter:user:{userID}
- //獲取指定的指定計數(shù)器
- HMGET counter:user:{userID} praiseCnt hostCnt
- //指定點贊數(shù)+1
- HINCRBY counter:user:{userID} praiseCnt
總結
1、c#本身有l(wèi)ock機制,單體模式可以使用。
2、但是考慮到我們的分布式部署,建議還是用緩存。在大并發(fā)的情況下,程序各種情況的發(fā)生。特別是涉及到金額操作。所以在大并發(fā)要互斥的情況下可以考慮2、3兩種方案。
當前標題:面試官扎心一問:防止重復請求提交,有什么方案?
網(wǎng)頁地址:http://www.5511xx.com/article/cdschpj.html


咨詢
建站咨詢
