隐藏

C# 实现 分布式 集群 Redis加锁与解锁

发布:2020/12/31 15:03:05作者:管理员 来源:本站 浏览次数:1626

Redis 加锁与解锁类,引用 using StackExchange.Redis;

/// <summary>
/// redis分布式锁
/// 分布式锁四要素
/// 1、锁名
/// 2、加锁
/// 3、解锁
/// 4、锁超时时间
/// </summary>
class RedisLock
    // 1、redis连接管理类
    private ConnectionMultiplexer connectionMultiplexer = null;
 
    // 2、redis数据操作类
    private IDatabase database = null;
    public RedisLock()
    {
        connectionMultiplexer = ConnectionMultiplexer.Connect("localhost:6379");
 
        database = connectionMultiplexer.GetDatabase(0);
    }
 
 
    /// <summary>
    /// 加锁
    /// 1、成功
    /// 2、失败
    /// </summary>
    public bool Lock()
    {
        ///1、key 锁名
        ///2、value 锁对象(谁锁的锁)
        ///3、expire 锁过期时间(防死锁)
        // 1、redis加锁
        // 如何说加锁失败,怎么办?继续获取嘛
        for (int i = 0; i < 10; i++)
        {
            bool flag = database.LockTake("redis_lock", Thread.CurrentThread.ManagedThreadId, TimeSpan.FromSeconds(10));
 
            if (flag)
            {
                return flag;
            }
 
            // 防止死循环导致内存溢出问题
            Thread.Sleep(20);
        }
        return false;
    }
 
    /// <summary>
    /// 解锁(释放锁占用资源)
    /// </summary>
    public bool Unlock()
    {
        // 1、redis解锁
        bool flag =  database.LockRelease("redis_lock", Thread.CurrentThread.ManagedThreadId);
 
        // 2、释放redis资源
        connectionMultiplexer.Close();
        return flag;
    }
 
}

下面是调用加锁与解锁和一些业务操作

/// <summary>
/// 秒杀方法
/// </summary>
public void SkillProduct()
{
    RedisLock redisLock = new RedisLock();
    if (redisLock.Lock())
    {
        // 1、获取商品库存
        int productCount = 从数据库获取商品个数据
 
 
       // 2、判断商品库存是否为空
        if (productCount == 0)
        {
            // 2.1 秒杀失败消息
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:不好意思,秒杀已结束");
            redisLock.Unlock();
            return;
        }
 
        // 3、秒杀成功消息
        Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:恭喜你,秒杀成功,商品编号:从数据库里面查询出来的编号");
 
        // 4、扣减商品库存
        productCount--;
 
        redisLock.Unlock();
    }
}