第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 }

在并发控制下,线程排队执行结果:数据被顺序更新

 


 

 

 

 

原文地址:https://www.cnblogs.com/WechatDeveloper/p/SenparcWeixinSDK-Course-7.html