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 }