当前位置: 首页 > article >正文

[001-03-007].第26节:分布式锁迭代1->基于setnx命令实现分布式锁:

我的博客大纲

我的后端学习大纲


1、setnx命令:


2、逻辑梳理:

  • 1.借助于redis中的命令setnx(key, value),key不存在就新增,存在就什么都不做。同时有多个客户端发送setnx命令,只有一个客户端可以成功,返回1(true);其他的客户端返回0(false)。
    在这里插入图片描述
    1.多个客户端同时获取锁(setnx)
    2.获取成功,执行业务逻辑,执行完成释放锁(del)
    3.其他客户端等待重试

3、编码实现:

  • 1.改造StockService方法:
@Service
public class StockService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    
    public void deduct() {
        // 加锁setnx
        Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111");
        // 如果没有抢到锁,那么就进行重试:实现递归调用
        if (!lock){
            try {
                Thread.sleep(50);
                this.deduct();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            try {
                // 1. 查询库存信息
                String stock = redisTemplate.opsForValue().get("stock").toString();

                // 2. 判断库存是否充足
                if (stock != null && stock.length() != 0) {
                    Integer st = Integer.valueOf(stock);
                    if (st > 0) {
                        // 3.扣减库存
                        redisTemplate.opsForValue().set("stock", String.valueOf(--st));
                    }
                }
            } finally {
                // 解锁
                this.redisTemplate.delete("lock");
            }
        }
    }
}
  • 2.其中,加锁也可以使用循环:
// 加锁,获取锁失败重试
while (!this.redisTemplate.opsForValue().setIfAbsent("lock", "111")){
    try {
        Thread.sleep(40);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
  • 3.解锁:
// 释放锁
this.redisTemplate.delete("lock");

4、使用Jmeter压力测试

在这里插入图片描述
在这里插入图片描述


http://www.kler.cn/a/300563.html

相关文章:

  • 项目实战--网页五子棋(游戏大厅)(3)
  • 第12篇:从入门到精通:掌握python高级函数与装饰器
  • redis-排查命中率降低问题
  • 日志收集Day002
  • 1.6 从 GPT-1 到 GPT-3.5:一路的风云变幻
  • Qt的核心机制概述
  • 08-图8 How Long Does It Take(C)
  • Java中的linkedList类及与ArrayList的异同
  • PoS 和 PoW 矿机系统区块链公链开发成本分析
  • 朴素贝叶斯 (Naive Bayes)
  • vue + Element UI table动态合并单元格
  • 前端CSS面试常见题
  • c#中的版本管理和描述
  • 函数的定义
  • Unity3d俯视视角下,通过点击屏幕获取世界坐标是如何实现的
  • windows通过wsl2安装linux系统之Ubuntu,傻瓜式安装
  • C++常用设计模式
  • 数据库视图和索引
  • 【iOS】Masnory的简单学习
  • 【PyQt6 应用程序】在用户登录界面实现密码密文保存复用
  • 若依RuoYi项目环境搭建教程(RuoYi-Vue + RuoYi-Vue3版本)
  • 在Faster Rcnn 中,rpn网络是单独训练的吗
  • django学习入门系列之第十点《A 案例: 员工管理系统5》
  • 设置ssh连接超时自动断开
  • 网络安全工程师填补人才缺口
  • SpringSecurity原理解析(五):HttpSecurity 类处理流程