Redis 分布式锁

【图灵学院】分布式架构-Redis高并发分布式锁

使用 Redis 当做分布式锁的核心就是 Redis 的 setnx 命令,setnx 命令 Redis 会保证只有一个线程设置成功。

注意点:

  • 释放锁操作必须在 finally 里执行,保证锁的成功释放。
  • key 必须设置过期时间,避免因系统异常、线程崩溃导致 key 一直存在,引发死锁。
  • 设置过期时间必须使用 setnx(key,vaule,expiredTime) 的原子操作。
  • 释放锁,必须保证只能是持有锁的线程来进行释放,因此可以为每个线程分配个唯一编号,然后设置为 key 的值,删除时进行判断。
  • key 的过期时间到了后,如果业务代码还未执行完,那么需要考虑为 key 延长过期时间,即续命。

最简陋的使用方式如下:

java 复制代码
public String deductStock() throws InterruptedException {
    String lockKey = "product_001";
    // String clientId = UUID.randomUUID().toString();
    RLock redissonLock = redisson.getLock(lockKey);
    try {
        // jedis.setnx(key,value)
        // Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "zhuge");
        //stringRedisTemplate.expire(lockKey,30, TimeUnit.SECONDS);
        /* Boolean result = stringRedisTemplate.opsForValue()
        		.setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

            if (!result) {
                return "1001";
            }*/

        // 加锁,实现锁续命功能
        redissonLock.lock();
        // jedis.get("stock")
        int stock = Integer.parseInt(Objects.requireNonNull(stringRedisTemplate.opsForValue().get("stock")));
        if (stock > 0) {
            int realStock = stock - 1;
            // jedis.set(key,value)
            stringRedisTemplate.opsForValue().set("stock", realStock + "");
            System.out.println("扣减成功,剩余库存:" + realStock + "");
        } else {
            System.out.println("扣减失败,库存不足");
        }
    } finally {
        redissonLock.unlock();
        // 这里也是有可能有问题的 有可能线程 A 刚进入到 if 里,然后被挂起了,而线程 B 加锁成功了,
        // 此时也会发生线程 A 删除了线程 B 的锁
        /*if (clientId.equals(stringRedisTemplate.opsForValue().get(lockKey))){
        	stringRedisTemplate.delete(lockKey);
        }*/
    }
    return "end";
}

同一个商品的并发 --> 可以对库存进行分段,使用分段锁来提高并发

相关推荐
董可伦16 分钟前
Spark 数据倾斜:原因、定位与处理方法
大数据·分布式·spark
deli0070071 小时前
JSON 树形查看器:粘贴即解析,折叠展开一目了然
前端·数据库·json·ai编程
国科安芯1 小时前
轨道供电韧性:ASP4644四通道降压架构在低轨卫星平台电源管理中的适用性分析
运维·网络·数据库·嵌入式硬件·架构·状态模式·低轨卫星星座
破土士V2 小时前
MySQL基础知识集合
数据库·mysql
笃行3502 小时前
达梦 VS 金仓:数据库替换项目里,迁移工具的差距体现在哪一层
数据库
笃行3502 小时前
向量数据库之后,一份合同为什么在五个库里对不上
数据库
笃行3502 小时前
数据库迁移工具装在一台笔记本上的年代,该翻篇了
数据库
笃行3502 小时前
一张表底下几千个分片:金仓时序数据库的超表怎么工作
数据库
whcyhhh2 小时前
头歌实践教学平台:数据科学与大数据技术导论(七上)
大数据·数据库·python
夕除3 小时前
redis--007
数据库·分布式