Redis用作分布式锁

亦碎流年 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();
        }
    }
}

运行效果如下:

相关推荐

DiamondTao / 0评论 2020-08-30