Redis 分布式锁

先理解线程锁,线程锁 就是锁住线程的锁

分布式锁就是锁住进程的锁

 

 

 在集群的环境下应该使用锁进程的方式

 

 

 

 1 using StackExchange.Redis;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace RedisCommon
 9 {
10     public class RedisLock
11     {
12         // 1、redis连接管理类
13         private ConnectionMultiplexer connectionMultiplexer = null;
14 
15         // 2、redis数据操作类
16         private IDatabase database = null;
17 
18         public RedisLock()
19         {
20             connectionMultiplexer = ConnectionMultiplexer.Connect("192.168.0.190:6379");
21 
22             database = connectionMultiplexer.GetDatabase(0);
23         }
24 
25         /// <summary>
26         /// 加锁
27         /// 1、key:锁名称
28         /// 2、value:谁加的这把锁。线程1
29         /// 3、exprie:过期时间:目的是为了防止死锁
30         /// 4、这里的过期时间要计算业务时间 要比业务时间长些
31         /// </summary>
32 
33         public void Lock()
34         {
35             while (true)
36             {
37                 //Thread.CurrentThread.ManagedThreadId 使用线程id 代替 进程id
38                 bool flag = database.LockTake("redis-lock", Thread.CurrentThread.ManagedThreadId, TimeSpan.FromSeconds(60));
39                 // 1、true 加锁成功 2、false 加锁失败
40                 //如果10个进程 那么只能有1个进程加锁成功,其他9个加锁失败,其他9个也需要加锁,所以需要其他
41                 //9个等待加锁 这里使用while循环,
42                 // flag 加锁成功 跳出循环
43                 // flag =false 加锁失败 睡眠60秒等待 上一个加锁成功的进程释放 进行下一次加索循环
44                 if (flag)
45                 {
46                     break;
47                 }
48                 // 防止死循环。通过等待时间,释放资源
49                 Thread.Sleep(60);
50             }
51         }
52 
53         /// <summary>
54         /// 解锁
55         /// </summary>
56 
57         public void UnLock()
58         {
59             bool flag = database.LockRelease("redis-lock", Thread.CurrentThread.ManagedThreadId);
60 
61             // true:释放成功  false 释放失败
62             // 方案:释放资源
63             connectionMultiplexer.Close();
64         }
65     }
66 }

webapi 调用

 1         /// <summary>
 2         /// 扣减商品库存
 3         /// </summary>
 4         /// <returns></returns>
 5         [HttpGet("SubStock")]
 6         public IActionResult SubStock()
 7         {
 8             #region 1、扣减库存流程
 9             {
10 
11                 RedisLock redisLock = new RedisLock();
12                 redisLock.Lock();
13                 //获取商品库存
14                 var stocks =new Random().Next(0,9);
15 
16                 //判断商品库存是否为空
17                 if (stocks == 0)
18                 {
19                     //秒杀失败消息
20                     Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:不好意思,秒杀已结束,商品编号:{stocks}");
21                     //解锁
22                     redisLock.UnLock();
23                     return new JsonResult("秒杀失败");
24                 }
25 
26                 //秒杀成功消息
27                 Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:恭喜你,秒杀成功,商品编号:{stocks}");
28 
29                 //扣减商品库存
30               //  subtracProductStocks(stocks);
31                 //解锁
32                 redisLock.UnLock();
33                 return new JsonResult("秒杀成功");
34             }
35             #endregion
36 
37             #region 2、扣减库存流程-单机并发
38             {
39 
40             }
41             #endregion
42 
43             #region 3、扣减库存流程-集群并发
44             {
45             }
46             #endregion
47 
48             return new JsonResult("秒杀成功");
49         }

 

posted on 2023-02-01 16:44  是水饺不是水饺  阅读(74)  评论(0编辑  收藏  举报

导航