第7課 快取策略及併發場景下的分散式鎖
阿新 • • 發佈:2020-07-18
課程地址: https://study.163.com/course/courseMain.htm?courseId=1004873017
本課專案地址:https://github.com/wechatdeveloper/WechatVideoCourse
課程目標:瞭解Senparc.Weixin SDK 快取策略;模擬多執行緒訪問產生的併發,使用分散式鎖控制併發
Redis 安裝:
-
開啟Redis服務,預設埠是6379;redis-cli.exe Set Key , Get Key
-
Redis Desktop Manager:https://github.com/uglide/RedisDesktopManager
-
下載地址:https://github.com/uglide/RedisDesktopManager/releases/tag/0.8.8
-
專案引用 Senparc.Weixin.Cache.Redis
-
Web.config 配置使用快取:
<add key="Cache_Redis_Configuration" value="localhost:6379" />
-
Global.asax 註冊測試號,參考Senparc Sample 專案配置方法
-
多執行緒並行,模擬併發
-
多個程序對同1個數據進行更新操作的時候,會產生併發的情況
-
控制併發的產生需要加鎖,也就程序更新資料的時候加鎖,更新完成後釋放鎖;加鎖的過程中,其他需要訪問資料的進行,排隊等候
-
建立LockTest方法,方法中對Static型別資料進行更新操作
- 單元測試中,開啟多個執行緒 執行LockTest()方法模擬資料併發,會發現在搶著更新資料,導致髒讀
1 //Static 儲存在記憶體中,頁面觀察資料變化 2 privatestatic int _count; 3 4 public static int Count 5 { 6 get { Thread.Sleep(50); return _count; } 7 8 set 9 { 10 //執行緒休眠0.1秒;模擬資料更新處理的時間 11 Thread.Sleep(100); 12 _count = value; 13 } 14 } 15 16 public ContentResult LockTest() 17 { 18 var count = Count; //資料計出來 19 Count = count + 1; //資料再更新進去 20 21 string strResult = "Count:"+ count; 22 23 return Content(strResult); 24 }
- 單元測試中,開啟多個執行緒 執行LockTest()方法模擬資料併發,會發現在搶著更新資料,導致髒讀
private int totalThread = 100; //計劃執行緒要執行次數 private int finishedThread = 0; [TestMethod] public void LockTest() { //開啟多個執行緒 for (int i = 0; i < 100; i++) { Thread.Sleep(100);//給個執行緒建立時間 Thread thread = new Thread(RunSingleLockTest); thread.Start(); } while (finishedThread!= totalThread) { //等待執行緒執行到100次 } Console.WriteLine("執行緒執行完畢:"+totalThread.ToString()); } private void RunSingleLockTest() { HomeController controller = new HomeController(); ContentResult result = controller.LockTest() as ContentResult; Console.WriteLine(result.Content); finishedThread++; //記得執行緒執行的次數 }
執行結果:
1 public ContentResult LockTest() 2 { 3 //獲取當前快取例項 4 var strategy = CacheStrategyFactory.GetObjectCacheStrategyInstance(); 5 using (strategy.BeginCacheLock("HomeController", "LockTest")) 6 { 7 var count = Count; //資料計出來 8 Count = count + 1; //資料再更新進去 9 string strResult = "Count:" + count; 10 return Content(strResult); 11 } 12 }
在併發控制下,執行緒排隊執行結果:資料被順序更新