使用 lock4j-redis-template-spring-boot-starter 实现redis分布式锁

使用 lock4j-redis-template-spring-boot-starter 实现redis分布式锁

    • 1. 引入依赖
    • 2. 配置 Redis
    • 3. 使用分布式锁
    • 4. 自定义锁配置
    • 5. 处理锁获取失败的情况
    • 6. 高级用法
    • 7.样例

分布式锁是一种用于在分布式系统中实现并发控制的机制。在分布式系统中,由于多个节点同时访问共享资源,会出现脏读、写冲突等并发问题。分布式锁通过在共享资源的访问前获取锁,来限制只有一个节点可以访问共享资源,从而保证在同一时间只有一个节点可以执行共享资源的操作,避免并发问题的发生。

分布式锁需要满足以下特点:

互斥性:同一时刻只能有一个节点可以获取到锁,其他节点需要等待。
可重入性:同一节点在获取到锁后可以再次获取锁,避免死锁的发生。
安全性:分布式锁需要保证在各种异常情况下都能正确释放锁,避免出现死锁、资源泄露等问题。
高可用性:分布式锁需要在多个节点之间实现协调,保证在节点故障时能够正确进行锁的转移和释放。
常见的分布式锁实现方式有基于数据库、基于缓存、基于ZooKeeper等。选择哪种实现方式要根据具体的业务场景和需求来决定。
现在使用redis缓存来实现简单的分布式锁。

1. 引入依赖

首先,在你的 Spring Boot 项目的 pom.xml 文件中添加 lock4j-redis-template-spring-boot-starter 和 Redis 的相关依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><dependency><groupId>com.baomidou</groupId><artifactId>lock4j-redis-template-spring-boot-starter</artifactId><version>2.2.7</version>
</dependency>

确保依赖的版本是最新的,可以去 Maven Central 查询最新版本。

2. 配置 Redis

在 application.properties 或 application.yml 文件中配置 Redis 的连接信息:

application.properties:


spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=yourpassword

application.yml:

spring:redis:host: localhostport: 6379password: yourpassword

3. 使用分布式锁

lock4j-redis-template-spring-boot-starter 提供了简单的注解 @Lock4j,你可以在需要加锁的方法上使用该注解。下面是一个示例:


import com.baomidou.lock.annotation.Lock4j;
import org.springframework.stereotype.Service;@Service
public class YourService {@Lock4j(keys = {"#arg1", "#arg2"})public void yourMethod(String arg1, String arg2) {// 需要加锁的业务逻辑System.out.println("Method is locked with args: " + arg1 + ", " + arg2);// 模拟业务处理try {Thread.sleep(5000);  // 假设业务逻辑处理需要 5 秒} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

在上述示例中,yourMethod 方法在执行时会获取一个分布式锁,锁的 key 是由方法参数 arg1 和 arg2 的值组合而成。

4. 自定义锁配置

你还可以自定义锁的配置,比如锁的过期时间和获取锁的超时时间等。这些配置可以通过在 application.properties 或 application.yml 文件中进行设置:

application.properties:

lock4j.lock.expire = 30000  # 锁的过期时间,单位毫秒
lock4j.lock.timeout = 10000 # 获取锁的超时时间,单位毫秒

application.yml:


lock4j:lock:expire: 30000  # 锁的过期时间,单位毫秒timeout: 10000 # 获取锁的超时时间,单位毫秒

5. 处理锁获取失败的情况

在一些情况下,如果获取锁失败,你可能需要处理这种情况。例如,可以抛出一个异常或者进行重试:


import com.baomidou.lock.annotation.Lock4j;
import com.github.yitter.lock.exception.LockException;
import org.springframework.stereotype.Service;@Service
public class YourService {@Lock4j(keys = {"#arg1", "#arg2"})public void yourMethod(String arg1, String arg2) {try {// 需要加锁的业务逻辑System.out.println("Method is locked with args: " + arg1 + ", " + arg2);// 模拟业务处理Thread.sleep(5000);  // 假设业务逻辑处理需要 5 秒} catch (InterruptedException e) {Thread.currentThread().interrupt();} catch (LockException e) {System.err.println("Failed to acquire lock: " + e.getMessage());// 处理获取锁失败的情况}}
}

6. 高级用法

除了简单的注解用法,lock4j-redis-template-spring-boot-starter 还支持更高级的用法,例如:

手动管理锁:你可以通过 Lock4j 提供的 API 手动管理锁。
自定义锁策略:你可以实现自己的锁策略来满足特定需求。

7.样例


import lombok.Data;@Data
public class CompanyInfo {private Long id;private Long gg;
}

没加锁:

 @GetMapping("/lockMethod")// @Lock4j(keys = {"#companyInfo.gg"}, acquireTimeout = 50000L, expire = 30000L)public String lockMethod(@RequestBody CompanyInfo companyInfo) throws InterruptedException {Thread.sleep(2000);log.info("Current tt companyInfo: " + companyInfo);return companyInfo.getGg().toString();}

输出结果:

2024-06-26 12:03:02.364  INFO 38028 --- [io-54555-exec-7] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.364  INFO 38028 --- [io-54555-exec-6] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.364  INFO 38028 --- [io-54555-exec-9] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.364  INFO 38028 --- [io-54555-exec-4] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.364  INFO 38028 --- [io-54555-exec-8] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.364  INFO 38028 --- [io-54555-exec-3] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.364  INFO 38028 --- [io-54555-exec-5] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.365  INFO 38028 --- [io-54555-exec-2] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.365  INFO 38028 --- [o-54555-exec-10] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:02.365  INFO 38028 --- [io-54555-exec-1] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:03:03.777  INFO 38028 --- [o-54555-exec-20] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.777  INFO 38028 --- [o-54555-exec-11] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.777  INFO 38028 --- [o-54555-exec-13] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.777  INFO 38028 --- [o-54555-exec-16] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.777  INFO 38028 --- [o-54555-exec-14] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.777  INFO 38028 --- [o-54555-exec-15] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.779  INFO 38028 --- [o-54555-exec-18] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.779  INFO 38028 --- [o-54555-exec-19] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.779  INFO 38028 --- [o-54555-exec-12] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:03:03.780  INFO 38028 --- [o-54555-exec-17] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)

结果得知,抢占资源

加了分布式锁:

/*** 使用分布式锁演示一个方法,其主要目的是为了锁定特定的键。** @param companyInfo 包含用于锁键信息的对象。* @return 公司GG值的字符串表示。* @throws InterruptedException 如果线程被中断。*/@GetMapping("/lockMethod")@Lock4j(keys = {"#companyInfo.gg"}, acquireTimeout = 50000L, expire = 30000L)public String lockMethod(@RequestBody CompanyInfo companyInfo) throws InterruptedException {Thread.sleep(2000);log.info("Current tt companyInfo: " + companyInfo);return companyInfo.getGg().toString();}

使用压测工具apipost并发10次可以测试得到:

2024-06-26 12:01:02.754  INFO 34972 --- [o-54555-exec-26] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:03.562  INFO 34972 --- [o-54555-exec-32] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:04.841  INFO 34972 --- [io-54555-exec-6] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:05.636  INFO 34972 --- [o-54555-exec-40] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:06.890  INFO 34972 --- [io-54555-exec-4] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:07.712  INFO 34972 --- [o-54555-exec-38] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:08.946  INFO 34972 --- [io-54555-exec-7] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:09.745  INFO 34972 --- [o-54555-exec-39] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:11.015  INFO 34972 --- [o-54555-exec-12] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:11.791  INFO 34972 --- [o-54555-exec-36] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:13.067  INFO 34972 --- [o-54555-exec-30] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:13.862  INFO 34972 --- [o-54555-exec-35] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:15.108  INFO 34972 --- [o-54555-exec-18] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:15.920  INFO 34972 --- [o-54555-exec-33] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:17.157  INFO 34972 --- [o-54555-exec-11] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:17.953  INFO 34972 --- [o-54555-exec-37] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:19.228  INFO 34972 --- [o-54555-exec-16] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:20.008  INFO 34972 --- [o-54555-exec-41] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)
2024-06-26 12:01:21.266  INFO 34972 --- [o-54555-exec-29] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=1111, gg=222)
2024-06-26 12:01:22.111  INFO 34972 --- [o-54555-exec-34] c.r.R.r.controller.RedisDemoController   : Current tt companyInfo: CompanyInfo(id=44, gg=44)

由上面可以得出,加了分布式锁可以解决资源公用的问题。

总结
通过上述步骤,你可以使用 lock4j-redis-template-spring-boot-starter 快速在 Spring Boot 项目中实现基于 Redis 的分布式锁。该 starter 提供了简洁的注解方式,方便开发者在业务逻辑中使用分布式锁。同时,你还可以根据需要进行自定义配置,以满足不同的业务需求。

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

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

相关文章

grpc学习golang版( 二、入门示例)

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 文章目录 一、环境二、编写protobuf文件三、编写server服务端四、编写服务端五、测试 一、环境 确保环境已经配置完成&#xff0c;效果如下。不同环境可能导致后续生成的效果不一。 go version protoc --version…

非对称加密介绍

非对称加密&#xff1a;现代网络安全的基石 在现代网络安全中&#xff0c;非对称加密是一种至关重要的技术。它在保护数据传输的机密性、完整性和真实性方面发挥着重要作用。本文将详细介绍什么是非对称加密、什么是公钥和私钥&#xff0c;以及它们在实际应用中的具体场景。 …

深度解析:ChatGPT是如何理解和生成自然语言文章的?

引言 随着人工智能的发展&#xff0c;ChatGPT作为一种先进的自然语言处理工具&#xff0c;正逐渐改变人们与技术交互的方式。那么&#xff0c;ChatGPT是如何理解和生成自然语言文章的&#xff1f;本文将从其技术原理、训练过程、实际应用等多个角度&#xff0c;深入解析这一过…

49、基于归一化感知器的输入向量分类(matlab)

1、基于归一化感知器的输入向量分类的原理及流程 归一化感知器是一种分类算法&#xff0c;其原理基于感知器算法&#xff0c;但是在输入向量上进行了归一化处理&#xff0c;以提高算法的性能和稳定性。 流程如下&#xff1a; 输入向量归一化&#xff1a;对每个输入向量进行归…

手机远程控制另一台手机的全新使用教程(安卓版)

看完这篇文章&#xff0c;你可以了解到安卓手机如何远程控制安卓手机&#xff0c;以及苹果手机如何远程控制安卓手机。 如果想要用安卓手机远程管控苹果手机&#xff0c;或者苹果手机远程管控另一台苹果手机&#xff0c;请点击查看视频《手机远程管控另一台手机的全新使用教程…

如何提高搜索点击率:五个利用ChatGPT创造吸引眼球标题的小技巧

在当今信息爆炸的时代&#xff0c;如何让自己的文章在海量信息中脱颖而出&#xff0c;是每个内容创作者都在思考的问题。尤其是当读者面对无数个搜索结果时&#xff0c;标题成为吸引他们点击的第一步。那么&#xff0c;如何才能写出吸引眼球的标题&#xff0c;从而提高搜索点击…

凯迪正大对电缆导体检测的重要性及其实施项目分享

电缆导体电缆的核心组成部分其性能直接影响到电缆的传输效率和使用寿命&#xff0c;所以对电缆导体进行定期检测确保其质量和性能对于保障电力设施的安全运行具有重要意义。今天就分享一下凯迪正大在电缆导体检测方面的心得总结&#xff0c;欢迎大家讨论并补充。 一、电缆导体…

论文学习_Towards Practical Binary Code Similarity Detection: Vulnerability

论文名称发表时间发表期刊期刊等级研究单位Towards Practical Binary Code Similarity Detection: Vulnerability 2023年ACM Transactions on Software Engineering and MethodologyCCF A信息工程研究所 1. 引言 重复性漏洞简介:开源库中的重复性漏洞,也称为 1-day 漏洞,由…

数字化工厂生产管理看板系统如何优化生产流程

在当今高度数字化的时代&#xff0c;制造业正经历着深刻的变革&#xff0c;数字化工厂生产管理看板系统作为一种创新的工具&#xff0c;正在为优化生产流程发挥着关键作用。 数字化工厂生产管理看板系统是一个集数据采集、分析、展示和决策支持于一体的综合性平台。生产管理看板…

SaaS行业的发展与前景

随着互联网技术的飞速发展&#xff0c;云计算逐渐成为新一代信息技术的重要方向。作为云计算的一种服务模式&#xff0c;SaaS&#xff08;Software as a Service&#xff0c;软件即服务&#xff09;已经深入到企业级应用和个人消费市场&#xff0c;成为全球软件产业的新趋势。在…

Linux上搭建邮件服务

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 Linux上搭建邮件服务 前言电子邮件的工作原理和基本组成部分1. 电子邮件的工作原理2. 电子邮件的…

【软件测试】概念篇

&#x1f383;&#x1f383;&#x1f383;个人主页&#x1f383;&#x1f383;&#x1f383; &#x1f383;&#x1f383;&#x1f383;【软件测试专栏】&#x1f383;&#x1f383;&#x1f383; &#x1f383;&#x1f383;&#x1f383;上一篇文章&#xff1a;认识测试&…

性能测试中关注的指标

性能测试中我们会关注很多的性能指标,会通过观测的性能指标来决定性能测试是否继续执行、性能测试是否通过等等内容,但是每次说到要监控什么指标的时候,往往就纠结在服务器的CPU利用率、可用内存数、磁盘IO、网络吞吐等,这些都是ISO25010定义的资源特性中给出的例子,其实对…

音乐创作与制作软件:Studio One 6.6.1中文版安装激活使用指南

音乐创作与制作软件&#xff1a;Studio One 6.6.1 简介 StudioOne 的设计核心是易于使用。十年来&#xff0c;它已将久经考验的录音棚模型与当今以节拍和循环为导向的制作过程无缝地结合在一起&#xff0c;因此您可以比以往更快地将音乐创意带入声音现实。高效的单屏幕界面可…

嵌入式Linux:开发平台搭建

目录 简介 1. JTAG工具的使用 2. 使用串口工具 3. 安装交叉编译工具 4.NFS文件的使用 简介 嵌入式开发平台的搭建,也即安装交叉编译工具链。 交叉编译是在一种平台上编译出能运行于另一种平台上的程序。 例如在X86平台上编译出能运行于ARM平台上的程序。 由于嵌入式设备…

04-Mysql 索引,事务

MySQL 索引介绍 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址。在数据十分庞大的时候&#xff0c;索引可以大大加快查询的速度。这是因为使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是先通过索引表找到该行…

PointCloudLib-特征(Features)-基于转动惯量和偏心率的描述符

基于转动惯量和偏心率的描述符 在本教程中,我们将学习如何使用 pcl::MomentOfInertiaEstimation 类来获取基于 偏心率和转动惯量。此类还允许提取云的轴对齐和定向边界框。 但请记住,提取的 OBB 不是最小可能的边界框. 理论入门 特征提取方法的思路如下。 首先计算点云的…

鸿蒙开发:1.环境搭建和入门

环境搭建 安装HUAWEI DevEco Studio 简介 HUAWEI DevEco Studio是基于IntelliJ IDEA Community开源版本打造&#xff0c; 为运行在HarmonyOS和OpenHarmony系统上的应用和服务提供一站式的开发平台。 特点 1.高效智能代码编辑&#xff1a;支持ArkTS、JS、C/C等语言的代码高亮、…

GNU、Unix、Linux、Makefile、GCC、GDB 之间的关系

1.1 Makefile Makefile 是一个用于自动化编译和构建过程的文本文件&#xff0c;尤其在软件开发项目中被广泛使用。它定义了一系列规则&#xff0c;说明了如何将源代码文件编译成可执行文件、库或者其他目标文件。Makefile 的核心作用在于它能够管理源代码文件之间的依赖关系&am…

Python多线程技巧心得详解

概要 多线程是一种能够并发执行代码的方法,可以提高程序的执行效率和响应速度。本文将详细介绍 Python 中多线程的概念、使用场景、基本用法以及实际应用,可以更好地掌握多线程编程。 什么是多线程? 多线程是一种在单个进程内并发执行多个线程的技术。每个线程共享相同的内…