Redis分布式锁的使用案例

news2024/9/22 1:18:27

一、引入依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.5.0</version>
</dependency>

二、工具类 

package com.hl.redisdemo.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

import java.util.Collections;

public class RedissonLockUtil {
    private static final Jedis jedis = new Jedis("localhost", 6379);

    /**
     * 可重入锁加锁
     * @param lockKey 锁的key
     * @param requestId 请求标识
     * @param expireTime 超时时间
     * @return 是否成功获取锁
     */
    public static boolean lock(String lockKey, String requestId, int expireTime) {
        SetParams params = new SetParams();
        params.nx().px(expireTime); // 设置nx和px参数,保证只在不存在该key时设置值,并设置过期时间
        String result = jedis.set(lockKey, requestId, params);
        return "OK".equalsIgnoreCase(result);
    }

    /**
     * 可重入锁解锁
     * @param lockKey 锁的key
     * @param requestId 请求标识
     * @return 是否成功释放锁
     */
    public static boolean unlock(String lockKey, String requestId) {
        String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(luaScript, Collections.singletonList(lockKey), Collections.singletonList(requestId));
        Long RELEASE_SUCCESS = 1L;
        return RELEASE_SUCCESS.equals(result);
    }

    /**
     * 获取可重入锁
     * @param lockKey 锁的key
     * @param requestId 请求标识
     * @param expireTime 超时时间
     * @return 是否成功获取锁
     */
    public static boolean tryLock(String lockKey, String requestId, int expireTime) {
        SetParams params = new SetParams();
        params.nx().px(expireTime); // 设置nx和px参数,保证只在不存在该key时设置值,并设置过期时间
        String result = jedis.set(lockKey, requestId, params);
        return "OK".equalsIgnoreCase(result);
    }
}

 三、测试代码

package com.hl.redisdemo.controller;

import com.hl.redisdemo.util.RedissonLockUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

/**
 * @author hulei
 * @date 2024/2/6 17:23
 */

@RestController
public class RedisDemoController {

    @RequestMapping("/redisTest")
    public String redisTest() throws InterruptedException {
        String str;
        String lockKey = "myLock";
        String requestId = UUID.randomUUID().toString(); // 生成唯一请求标识
        // 集群场景下,锁超时时间应该保证大于多数节点获取锁的时间
        //当发生在多数节点获取锁的时间大于锁超时时间时,获取到的锁在各节点早已超时失效,锁失效
        int expireTime = 5000; // 锁的过期时间为5秒,注意,
        // 尝试获取锁
        if (RedissonLockUtil.tryLock(lockKey, requestId, expireTime)) {
            System.out.println("获取到锁");
            // 执行业务逻辑
            Thread.sleep(1000);
            // 释放锁
            if (RedissonLockUtil.unlock(lockKey, requestId)) {
                System.out.println("释放锁成功");
                str = "释放锁成功";
            } else {
                System.out.println("释放锁失败");
                str = "释放锁失败";
            }
        } else {
            System.out.println("获取锁失败");
            str = "获取锁失败";
        }
        return str;
    }
}

测试结果分析:

1.正常测试结果

 

正常匀速点击请求,每次等之前的请求完成后释放锁,后面的请求则能够正常获取锁

2.异常测试结果 :

如果点击速度过快,之前的请求业务逻辑没有执行完,锁还未释放,后面的请求获取锁时,则提示锁获取失败,这样就保证了业务执行的顺序性,正确性。使用场景 如防止订单超卖,库存扣减等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1437140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯Web应用开发-CSS3 新特性

CSS3 新特性 专栏持续更新中 在前面我们已经学习了元素选择器、id 选择器和类选择器&#xff0c;我们可以通过标签名、id 名、类名给指定元素设置样式。 现在我们继续选择器之旅&#xff0c;学习 CSS3 中新增的三类选择器&#xff0c;分别是&#xff1a; • 属性选择器 • 子…

Swin-UMamba:结合基于ImageNet的预训练和基于Mamba的UNet模型

摘要 https://arxiv.org/pdf/2402.03302v1.pdf 准确的医学图像分割需要整合从局部特征到全局依赖的多尺度信息。然而&#xff0c;现有方法在建模长距离全局信息方面面临挑战&#xff0c;其中卷积神经网络&#xff08;CNNs&#xff09;受限于其局部感受野&#xff0c;而视觉转换…

python学习21

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

回归预测 | Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测&#x…

JavaScript中闭包的定义、原理及应用场景

JavaScript是一门以函数为核心的编程语言&#xff0c;其独特的闭包特性是众多开发者所喜爱的特点之一。闭包是一种非常强大的概念&#xff0c;可以帮助我们实现许多复杂的功能和逻辑。本篇博客将为大家深入介绍JavaScript中闭包的定义、原理及应用场景&#xff0c;并通过示例代…

jpeg交叉编译(rv1126)

1.下载 官网下载地址 Independent JPEG Group (ijg.org) 2.解压 1)新建文件夹,解压源码(文件夹 jpeg-9f) 2)新建install-rv1126文件夹 具体目录结构如下图所示。 3.配置 1)进入源码文件夹jpeg-9f 2) export CC=/usr/bin/arm-linux-gnueabihf-gcc ./configure CC=…

Netty中使用编解码器框架

目录 什么是编解码器&#xff1f; 解码器 将字节解码为消息 将一种消息类型解码为另一种 TooLongFrameException 编码器 将消息编码为字节 将消息编码为消息 编解码器类 通过http协议实现SSL/TLS和Web服务 什么是编解码器&#xff1f; 每个网络应用程序都必须定义如何…

STM32Cubmax stm32f103zet6 SPI通讯

一、基本概念 SPI 是英语 Serial Peripheral interface 的缩写&#xff0c;顾名思义就是串行外围设备接口。是 Motorola 首先在其 MC68HCXX 系列处理器上定义的。 SPI 接口主要应用在 EEPROM&#xff0c; FLASH&#xff0c;实时时 钟&#xff0c; AD 转换器&#xff0c;还有数…

Ubuntu下anaconda的常用操作

Ubuntu下anaconda的安装及常用操作 安装Anaconda 下载Anaconda&#xff1a;在Anaconda官网下载适合你系统的Anaconda安装包&#xff08;通常是64位的Linux版本&#xff09;。 安装Anaconda 在终端中导航到你下载Anaconda安装包的目录&#xff0c;然后运行以下命令安装Anacon…

Verilog刷题笔记19

题目&#xff1a; A common source of errors: How to avoid making latches When designing circuits, you must think first in terms of circuits: I want this logic gate I want a combinational blob of logic that has these inputs and produces these outputs I want…

Avalonia学习(二十三)-大屏

弄一个大屏显示的界面例子&#xff0c;但是代码有点多&#xff0c;还有用户控件。 目前还有一点问题在解决&#xff0c;先看一下界面效果。

人工智能 | 深度学习的进展

深度学习的进展 深度学习是人工智能领域的一个重要分支&#xff0c;它利用神经网络模拟人类大脑的学习过程&#xff0c;通过大量数据训练模型&#xff0c;使其能够自动提取特征、识别模式、进行分类和预测等任务。近年来&#xff0c;深度学习在多个领域取得了显著的进展&#…

2024无参考图像的清晰度评价方法

无参考图像质量评价算法 无参考图像质量评价是指参考图像不存在的情况下&#xff0c;直接计算失真图像的视觉质量。根据无参考图像质量评价模型在计算图像视觉质量时是否需要图像的主观分数来进行训练&#xff0c;无参考图像质量评价算法可分为基于监督学习的无参考图像质量评价…

艺术创作和生活的关系

艺术出现在生产劳作中并体现出人们生活、工作、学习中&#xff0c;使人们在不受限制随意发挥缔造发明能力的体现&#xff0c;独立的精神活动领域在它逐渐演变进步的历程中越来越明显&#xff0c;也是一个人精神思想生活中很重要的一部分。艺术随着社会发展而发展。一件完美的艺…

神经网络的权重是什么?

请参考这个视频https://www.bilibili.com/video/BV18P4y1j7uH/?spm_id_from333.788&vd_source1a3cc412e515de9bdf104d2101ecc26a左边是拟合的函数&#xff0c;右边是均方和误差&#xff0c;也就是把左边的拟合函数隐射到了右边&#xff0c;右边是真实值与预测值之间的均方…

FPGA设计Verilog基础之Verilog全局变量和局部变量定义

注意&#xff1a;后续技术分享&#xff0c;第一时间更新&#xff0c;以及更多更及时的技术资讯和学习技术资料&#xff0c;将在公众号CTO Plus发布&#xff0c;请关注公众号&#xff1a;CTO Plus 在Verilog中&#xff0c;变量可以分为全局变量和局部变量两种类型。全局变量在整…

FLIP解读

title: FLIP解读 mathjax: true toc: true date: 2024-02-06 17:22:20 categories: Machine Learning tags:CLIPMasked AutoencodersContrastive Learning FLIP由CLIP改进而来&#xff0c;其思想非常简单&#xff0c;通过在图片侧mask掉相当比例的patch&#xff08;无须重构pa…

瑞萨RA6M3开发实践指南-UART实践

1.背景说明 本文是参考瑞萨RA6M3开发实践指南文章教程&#xff0c;基于瑞萨HMI-Board BSP :1.1.1 版本 RT-Thread 5.0.1 版本操作步骤进行记录&#xff0c;整理成的文档。 1.1 本章内容 使用RT-Thread Studio创建开发板的程序&#xff0c;编写UART的程序&#xff0c;实现串口…

万物皆可问 — 私有部署网易有道QAnything

什么是 QAnything&#xff1f; QAnything&#xff08;Question and Answer based on Anything&#xff09;是一个本地知识库问答系统&#xff0c;旨在支持多种文件格式和数据库&#xff0c;允许离线安装和使用。使用QAnything&#xff0c;您可以简单地删除本地存储的任何格式的…

Linux的打包压缩与解压缩---tar、xz、zip、unzip

最近突然用到了许久不用的压缩解压缩命令&#xff0c;真的陌生&#xff0c; 哈哈&#xff0c;记录一下&#xff0c;后续就不用搜索了。 tar的打包 tar -cvf 压缩有的文件名称 需要压缩的文件或文件夹tar -cvf virtualbox.tar virtualbox/ tar -zcvf virtualbox.tar virtualbo…