第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类型数据进行更新操作  

 1 //Static 保存在内存中,页面观察数据变化
 2         private static int _count;
 3 
 4         public static int Count
 5         {
 6             get { return _count; }
 7 
 8             set
 9             {
10                 _count = value;
11             }
12         }
13 
14         public ContentResult LockTest()
15         {
16             //获取当前缓存实例
17             var strategy = CacheStrategyFactory.GetObjectCacheStrategyInstance();
18             using (strategy.BeginCacheLock("HomeController", "LockTest"))
19             {
20                 Thread.Sleep(300);
21                 Count++;
22                 return Content("Count:" + Count);
23             }
24         }
View Code
  • 单元测试中,开启多个线程 执行LockTest()方法模拟数据并发,会发现在抢着更新数据,导致脏读 
 1 private int totalThread = 100; //计划线程要执行20次
 2         private int finishedThread = 0;
 3 
 4         [TestMethod]
 5         public void LockTest()
 6         { 
 7             //开启多个线程
 8             for (int i = 0; i < 100; i++)
 9             { 
10                 Thread thread = new Thread(RunSingleLockTest);
11                 thread.Start(); 
12             }
13 
14             while (finishedThread!= totalThread)
15             {
16                 //等待线程执行到100次
17             }
18 
19             Console.WriteLine("线程执行完毕:"+totalThread.ToString());
20          
21         }
22          
23         private void RunSingleLockTest()
24         {  
25             HomeController controller = new HomeController();
26 
27             ContentResult result = controller.LockTest() as ContentResult;
28 
29             Console.WriteLine(result.Content);
30 
31             finishedThread++; //记得线程执行的次数
32         }
View Code
  • 执行结果:

 

用缓存策略,控制并发:把数据读取、更新操作,加锁处理,控制线程排队执行 

 public ContentResult LockTest()
        {
            //获取当前缓存实例
            var strategy = CacheStrategyFactory.GetObjectCacheStrategyInstance();
            using (strategy.BeginCacheLock("HomeController", "LockTest"))
            {
                Thread.Sleep(300);
                Count++;
                return Content("Count:" + Count);
            }
        }
View Code

 

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

 

 

 

 


 

 

 

 

posted @ 2020-07-18 18:04  Wechat-Developer  阅读(257)  评论(0编辑  收藏  举报