1. 程式人生 > 實用技巧 >第7課 快取策略及併發場景下的分散式鎖

第7課 快取策略及併發場景下的分散式鎖

文章說明: 本文是基於盛派網路蘇震巍老師的《微信公眾號+小程式快速開發》課程筆記。

課程地址: https://study.163.com/course/courseMain.htm?courseId=1004873017

本課專案地址:https://github.com/wechatdeveloper/WechatVideoCourse

課程目標:瞭解Senparc.Weixin SDK 快取策略;模擬多執行緒訪問產生的併發,使用分散式鎖控制併發

Redis 安裝:

專案中使用Redis快取

  • 專案引用 Senparc.Weixin.Cache.Redis

  • Web.config 配置使用快取:<add key="Cache_Redis_Configuration" value="localhost:6379" />

  • Global.asax 註冊測試號,參考Senparc Sample 專案配置方法

  • 通過Redis Desktop Manager 查詢,已經有了 Senparc SDK 產生的快取資料:

  

  

多執行緒並行,模擬併發

  • 多個程序對同1個數據進行更新操作的時候,會產生併發的情況

  • 控制併發的產生需要加鎖,也就程序更新資料的時候加鎖,更新完成後釋放鎖;加鎖的過程中,其他需要訪問資料的進行,排隊等候

  • 建立LockTest方法,方法中對Static型別資料進行更新操作

  • 單元測試中,開啟多個執行緒 執行LockTest()方法模擬資料併發,會發現在搶著更新資料,導致髒讀
 1        //Static 儲存在記憶體中,頁面觀察資料變化
 2         private
static 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 }

在併發控制下,執行緒排隊執行結果:資料被順序更新