日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

浅谈C#在网络波动时防重复提交

發布時間:2023/12/4 C# 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈C#在网络波动时防重复提交 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????前幾天,公司數據庫出現了兩條相同的數據,而且時間相同(毫秒也相同)。排查原因,發現是網絡波動造成了重復提交。

????由于網絡波動而重復提交的例子也比較多:

????網絡上,防重復提交的方法也很多,使用redis鎖,代碼層面使用lock。

????但是,我沒有發現一個符合我心意的解決方案。因為網上的解決方案,第一次提交返回成功,第二次提交返回失敗。由于兩次返回信息不一致,一次成功一次失敗,我們不確定客戶端是以哪個返回信息為準,雖然我們希望客戶端以第一次返回成功的信息為準,但客戶端也可能以第二次失敗信息運行,這是一個不確定的結果。

在重復提交后,如果客戶端的接收到的信息都相同,都是成功,那客戶端就可以正常運行,就不會影響用戶體驗。

????我想到一個緩存類,來源于PetaPoco。

Cache<TKey,?TValue>代碼如下:


????Cache<TKey,?TValue>符合我的要求,第一次運行后,會將值緩存,第二次提交會返回第一次的值。

??? 但是,細細分析Cache<TKey, TValue> 類,可以發現有以下幾個缺點

?????????1、?不會自動清空緩存,適合一些key不多的數據,不適合做為網絡接口。

?????????2、?由于_lock.EnterWriteLock,多線程會變成并單線程,不適合做為網絡接口。

?????????3、?沒有過期緩存判斷。

????于是我對Cache<TKey,?TValue>進行改造。

AntiDupCache代碼如下:


代碼分析:

??????使用兩個ReaderWriterLockSlim鎖?+?一個AntiDupLockSlim鎖,實現并發功能。

????? Dictionary<TKey, Tuple<long, TValue>> _map實現緩存,long類型值記錄時間,實現緩存過期

??????int?_maxCount?+?Queue<TKey>?_queue,_queue?記錄key列隊,當數量大于_maxCount,清除多余緩存。

????? AntiDupLockSlim繼承ReaderWriterLockSlim,實現垃圾回收,

代碼使用?:


測試性能數據:

-----------------------?開始??從1到100???重復次數:1?單位:?ms?-----------------------

??????并發數量:?1????2????3????4????5????6????7????8????9????10???11???12

??????普通并發:?188??93???65???46???38???36???28???31???22???20???18???19

??AntiDupCache:?190??97???63???48???37???34???29???30???22???18???17???21

??AntiDupQueue:?188??95???63???46???37???33???30???25???21???19???17???21

?????DictCache:?185??96???64???47???38???33???28???29???22???19???17???21

?????????Cache:?185??186??186??188??188??188??184??179??180??184??184??176

第二次普通并發:?180??92???63???47???38???36???26???28???20???17???16???20

-----------------------?開始??從1到100???重復次數:2?單位:?ms?-----------------------

??????并發數量:?1????2????3????4????5????6????7????8????9????10???11???12

??????普通并發:?368??191??124??93???73???61???55???47???44???37???34???44

??AntiDupCache:?180??90???66???48???37???31???28???24???21???17???17???22

??AntiDupQueue:?181??93???65???46???39???31???27???23???21???19???18???19

?????DictCache:?176??97???61???46???38???30???31???23???21???18???18???22

?????????Cache:?183??187??186??182??186??185??184??177??181??177??176??177

第二次普通并發:?366??185??127??95???71???62???56???48???43???38???34???43

-----------------------?開始??從1到100???重復次數:4?單位:?ms?-----------------------

??????并發數量:?1????2????3????4????5????6????7????8????9????10???11???12

??????普通并發:?726??371??253??190??152??132??106??91???86???74???71???69

??AntiDupCache:?189??95???64???49???37???33???28???26???22???19???17???18

??AntiDupQueue:?184??97???65???51???39???35???28???24???21???18???17???17

?????DictCache:?182??95???64???45???39???34???29???23???21???18???18???16

?????????Cache:?170??181??180??184??182??183??181??181??176??179??179??178

第二次普通并發:?723??375??250??186??150??129??107??94???87???74???71???67

-----------------------?開始??從1到100???重復次數:12?單位:?ms?-----------------------

??????并發數量:?1????2????3????4????5????6????7????8????9????10???11???12

??????普通并發:?2170?1108?762??569??450??389??325??283??253??228??206??186

??AntiDupCache:?182??95???64???51???41???32???28???25???26???20???18???18

??AntiDupQueue:?189??93???67???44???37???35???29???30???27???22???20???17

?????DictCache:?184??97???59???50???38???29???27???26???24???19???18???17

?????????Cache:?174??189??181??184??184??177??182??180??176??176??180??179

第二次普通并發:?2190?1116?753??560??456??377??324??286??249??227??202??189

仿線上環境,性能測試數據:

-----------------------?仿線上環境??從1到1000??單位:?ms?-----------------------

??????并發數量:?1????2????3????4????5????6????7????8????9????10???11???12

??????普通并發:?1852?950??636??480??388??331??280??241??213??198??181??168

??AntiDupCache:?1844?949??633??481??382??320??267??239??210??195??174??170

??AntiDupQueue:?1835?929??628??479??386??318??272??241??208??194??174??166

?????DictCache:?1841?935??629??480??378??324??269??241??207??199??176??168

?????????Cache:?1832?1854?1851?1866?1858?1858?1832?1825?1801?1797?1788?1785

第二次普通并發:?1854?943??640??468??389??321??273??237??209??198??177??172

項目:

??????Github:https://github.com/toolgood/ToolGood.AntiDuplication

??????Nuget:?Install-Package?ToolGood.AntiDuplication

后記:

?????嘗試添加?一個Queue<AntiDupLockSlim>?或Stack<AntiDupLockSlim>?用來緩存鎖,后發現性能效率相差不大,上下浮動。

?????使用?lock關鍵字加鎖,速度相差不大,代碼看似更簡單,但隱藏了一個地雷:一般人使用唯一鍵都是使用string,就意味著可能使用lock(string),鎖定字符串尤其危險,因為字符串被公共語言運行庫?(CLR)“暫留”。?這意味著整個程序中任何給定字符串都只有一個實例,就是這同一個對象表示了所有運行的應用程序域的所有線程中的該文本。因此,只要在應用程序進程中的任何位置處具有相同內容的字符串上放置了鎖,就將鎖定應用程序中該字符串的所有實例。

原文地址:https://www.cnblogs.com/toolgood/p/10700828.html

.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?

總結

以上是生活随笔為你收集整理的浅谈C#在网络波动时防重复提交的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。