亦碎流年 2020-02-15
Redis用作分布式锁使用的业务逻辑
。。。
。。。
简单的使用案例如下(商品秒杀应用场景):
下面商品秒杀应用场景案例演示的前提是Redis已经安装,并可以使用,具体安装教程可以参考本文上篇文章 Redis概述与安装
1、使用Visual studio 2019 Enterprise 创建一个控制台项目 ConsoleTestRedis,选择项目右键,点击NuGet包管理器 ,搜索并添加 StackExchange.Redis
2、添加客户端请求类 Client,商品秒杀 ProductKill ,Redis分布式锁 RedisLock 类
客户端请求类 Client代码如下:
using System.Threading; namespace ConsoleTestRedis { /// <summary> /// 客户端请求 /// </summary> public class Client { public void CleitRequest() { ProductKill productKill = new ProductKill(); for (int i = 0; i < 20; i++) { new Thread(() => { productKill.KillProduct(); }).Start(); } } } }
商品秒杀 ProductKill代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleTestRedis { /// <summary> /// 商品秒杀 /// </summary> public class ProductKill { /// <summary> /// 库存数量 /// </summary> public int repositoryNumber = 10; /// <summary> /// 获取库存的数量 /// </summary> /// <returns></returns> public int GetRepositoryNumber() { return repositoryNumber; } /// <summary> /// 扣减库存数量 /// </summary> public void SetRepositoryNumber() { repositoryNumber--; ; } /// <summary> /// 商品秒杀 /// </summary> public void KillProduct() { //使用Redis分布式锁RedisLock RedisLock redisLock = new RedisLock(); redisLock.Lock(); var restory = GetRepositoryNumber(); if (restory == 0) { Console.WriteLine($" {Thread.CurrentThread.ManagedThreadId} 不好意思获取失败!商品库存数量:{repositoryNumber}"); redisLock.UnLock(); return; } Console.WriteLine($"恭喜 {Thread.CurrentThread.ManagedThreadId} 获取秒杀商品成功!商品库存数量:{repositoryNumber}"); SetRepositoryNumber(); redisLock.UnLock(); } } }
Redis分布式锁 RedisLock 类代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using StackExchange.Redis; namespace ConsoleTestRedis { /// <summary> /// Redis分布式锁 /// </summary> public class RedisLock { /// <summary> /// redis分布式连接管理器 /// </summary> public ConnectionMultiplexer _connectionMultiplexer { get; set; } /// <summary> /// 数据库 /// </summary> public IDatabase _database { get; set; } public RedisLock() { //使用的redis api 前提1、安装redis 2、NuGet包管理器添加 StackExchange.Redis _connectionMultiplexer = ConnectionMultiplexer.Connect("localhost:6379"); _database = _connectionMultiplexer.GetDatabase(0); } /// <summary> /// 锁住 /// </summary> public void Lock() { while (true) { //LockTake 参数说明 (锁名称,获取所得对象,过期时间) bool isLocked = _database.LockTake("redis_key", Thread.CurrentThread.ManagedThreadId, TimeSpan.FromSeconds(200)); if (isLocked) { break; } Thread.Sleep(200); } } /// <summary> /// 释放 /// </summary> public void UnLock() { //LockRelease 参数说明 (锁名称,获取所得对象) _database.LockRelease("redis_key", Thread.CurrentThread.ManagedThreadId); _connectionMultiplexer.Close(); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleTestRedis { class Program { static void Main(string[] args) { Console.WriteLine("。。。。。商品秒杀开始。。。。。。"); Client client = new Client(); client.CleitRequest(); Console.ReadKey(); } } }
运行效果如下: