分布式锁在Redis实现的一些注意事项

基于Redis实现分布式锁之前,这些坑你一定得知道 作者简介 陈寒立,一个不误正业的程序员。先后在物流金融组、物流末端业务组和压力平衡组打过杂,技术栈从Python玩到了Java,依然没学会好好写业务代码,梦想着用抽象的模型拯救业务于水火之中。 开头 基于Redis的分布式锁对大家来说并不陌生,可是你的分布式锁有失败的时候吗?在失败的时候可曾怀疑过你在用的分布式锁真的靠谱吗?以下是结合自己的踩坑经验总结的一些经验之谈。 你真的需要分布式锁吗? ... 阅读详情

前言

查看了不少关于redis实现分布式锁的文章,无疑要设计一个靠谱的分布式并不太容易,总会出现各种鬼畜的问题;现在就来小述一下,在设计一个分布式锁的过程中,会遇到一些什么问题

I. 背景知识

借助redis来实现分布式锁(我们先考虑单机redis的模式),首先有必要了解下以下几点:

单线程模式

setnx : 当不存在时,设置value,并返回1; 否则返回0

getset : 设置并获取原来的值

expire : 设置失效时间

get : 获取对应的值

del : 删除

ttl : 获取key对应的剩余时间,若key没有设置过超时时间,或者压根没有这个key则返回负数(可能是-1,-2)

watch/unwatch : 事务相关

II. 方案设计

1. 设计思路

获取锁:

调用 setnx 尝试获取锁,如果设置成功,表示获取到了锁

设置失败,此时需要判断锁是否过期

未过期,则表示获取失败;循环等待,并再次尝试获取锁

已过期,getset再次设置锁,判断是否获取了锁(根据返回的值进行判断,后面给出具体的方案)

若失败,则重新进入获取锁的逻辑

释放锁:

一个原则就是确保每个业务方释放的是自己的锁

2. getset的实现方案

网上一种常见的case,主要思路如下

setnx 尝试获取锁

失败,则 get 获取锁的value (一般是 uuid_timstamp)

判断是否过期,若没有过期,则表示真的获取失败

若过期,则采用 getset设置,尝试获取锁

实现代码如下

public class DistributeLock {

private static final Long OUT_TIME = 30L;

public String tryLock(Jedis jedis, String key) {

while (true) {

String value = UUID.randomUUID().toString() + "_" + System.currentTimeMillis();

Long ans = jedis.setnx(key, value);

if (ans != null && ans == 1) { // 获取锁成功

return value;

}

// 锁获取失败, 判断是否超时

String oldLock = jedis.get(key);

if (oldLock == null) {

continue;

}

long oldTime = Long.parseLong(oldLock.substring(oldLock.lastIndexOf("_") + 1));

long now = System.currentTimeMillis();

if (now - oldTime < OUT_TIME) { // 没有超时

continue;

}

String getsetOldVal = jedis.getSet(key, value);

if (Objects.equals(oldLock, getsetOldVal)) { // 返回的正好是上次的值,表示锁获取成功

return value;

} else { // 表示返回的是其他业务设置的锁,赶紧的设置回去

jedis.set(key, getsetOldVal);

}

}

}

public void tryUnLock(Jedis jedis, String key, String uuid) {

String ov = jedis.get(key);

if (uuid.equals(ov)) { // 只释放自己的锁

jedis.del(key);

}

}

}

观察获取锁的逻辑,特别是获取超时锁的逻辑,很容易想到有一个问题 ​​getSet​​​ 方法会不会导致写数据混乱的问题,简单来说就是多个线程同时判断锁超时时,执行 ​​getSet​​设置锁时,最终获取锁的线程,能否保证和redis中的锁的value相同

上面的实现方式,一个混乱的case如下:

三个线程a,b,c 都进入到了锁超时的阶段

线程a, 获取原始值 oldVal, 并设置 t1

线程b, 获取线程a设置的 t1, 并重设为 t2

线程c, 获取线程b设置的 t2, 并重设为 t3

线程a,判断,并正式获取到锁

线程b,判断失败,恢复原来锁的内容为t1

线程c, 判断失败,恢复原来锁的内容为t2

问题出现了,获取锁的线程a,期望所得内容为t1, 但是实际为t2; 导致无法释放锁

实际验证

在上面的代码中,配合测试case,加上一些日志输出

public static String tryLock(Jedis jedis, String key) throws InterruptedException {

String threadName = Thread.currentThread().getName();

while (true) {

String value = threadName + "_" + UUID.randomUUID().toString() + "_" + System.currentTimeMillis();

Long ans = jedis.setnx(key, value);

if (ans != null && ans == 1) { // 获取锁成功

return value;

}

// 锁获取失败, 判断是否超时

String oldLock = jedis.get(key);

if (oldLock == null) {

continue;

}

long oldTime = Long.parseLong(oldLock.substring(oldLock.lastIndexOf("_") + 1));

long now = System.currentTimeMillis();

if (now - oldTime < OUT_TIME) { // 没有超时

continue;

}

// 强制使所有的线程都可以到这一步

Thread.sleep(50);

System.out.println(threadName + " in getSet!");

// 人工接入,确保t1 获取到锁, t2 获取的是t1设置的内容, t3获取的是t2设置的内容

if ("t2".equalsIgnoreCase(threadName)) {

Thread.sleep(20);

} else if ("t3".equalsIgnoreCase(threadName)) {

Thread.sleep(40);

}

String getsetOldVal = jedis.getSet(key, value);

System.out.println(threadName + " set redis value: " + value);

if (Objects.equals(oldLock, getsetOldVal)) { // 返回的正好是上次的值,表示锁获取成功

System.out.println(threadName + " get lock!");

if ("t1".equalsIgnoreCase(threadName)) {

// t1获取到锁,强制sleep40ms, 确保线t2,t3也进入了 getSet逻辑

Thread.sleep(40);

}

return value;

} else { // 表示返回的是其他业务设置的锁,赶紧的设置回去

// 人肉介入,确保t2优先执行,并设置回t1设置的值, t3后执行设置的是t2设置的值

if ("t3".equalsIgnoreCase(threadName)) {

Thread.sleep(40);

} else if ("t2".equalsIgnoreCase(threadName)){

Thread.sleep(20);

}

jedis.set(key, getsetOldVal);

System.out.println(threadName + " recover redis value: " + getsetOldVal);

}

}

}

测试case

@Test

public void testLock() throws InterruptedException {

// 先无视获取jedis的方式

JedisPool jedisPool = cacheWrapper.getJedisPool(0);

Jedis jedis = jedisPool.getResource();

String lockKey = "lock_test";

String old = DistributeLock.tryLock(jedis, lockKey);

System.out.println("old lock: " + old);

// 确保锁超时

Thread.sleep(40);

// 创建三个线程

Thread t1 = new Thread(() -> {

try {

Jedis j =jedisPool.getResource();

DistributeLock.tryLock(j, lockKey);

System.out.println("t1 >>>> " + j.get(lockKey));

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "t1");

Thread t2 = new Thread(() -> {

try {

Jedis j =jedisPool.getResource();

DistributeLock.tryLock(j, lockKey);

System.out.println("t2 >>>>> " + j.get(lockKey));

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "t2");

Thread t3 = new Thread(() -> {

try {

Jedis j =jedisPool.getResource();

DistributeLock.tryLock(j, lockKey);

System.out.println("t3 >>>>> " + j.get(lockKey));

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "t3");

t1.start();

t2.start();

t3.start();

Thread.sleep(10000);

};

部分输出结果:

main in getSet!

main set redis value: main_d4cc5d69-5027-4550-abe1-10126f057779_1515643763130

main get lock!

old lock: main_d4cc5d69-5027-4550-abe1-10126f057779_1515643763130

t1 in getSet!

t2 in getSet!

t1 set redis value: t1_105974db-7d89-48bf-9669-6f122a3f9fb6_1515643763341

t1 get lock!

t3 in getSet!

t2 set redis value: t2_be06f80a-9b70-4a0e-a86d-44337abe8642_1515643763341

t1 >>>> t2_be06f80a-9b70-4a0e-a86d-44337abe8642_1515643763341

t3 set redis value: t3_9aa5d755-43b2-43bd-9a0b-2bad13fa31f6_1515643763345

t2 recover redis value: t1_105974db-7d89-48bf-9669-6f122a3f9fb6_1515643763341

t3 recover redis value: t2_be06f80a-9b70-4a0e-a86d-44337abe8642_1515643763341

重点关注 ​​t1 >>>> t2_be06f80a-9b70-4a0e-a86d-44337abe8642_1515643763341​​,表示t1线程过去了锁,但是锁的内容不是其value,即便t2去恢复,也会被t3给覆盖

如何解决上面这个问题呢?

上面是典型的并发导致的问题,当然可以考虑从解决并发问题的角度出发来考虑,一个常见的方式就是加锁了,思路如下:(不详细展开了)

在判断超时之后,加锁

再次获取对应的值,判断是否超时,是则执行上面的操作

否则退出逻辑,继续循环

这种实现方式,会有以下的问题:

getset 这个方法执行,可能导致写入脏数据

基于服务器时钟进行超时判断,要求所有服务器始终一致,否则有坑

3. expire实现方式

相比于前面一种直接将value设置为时间戳,然后来比对的方法,这里则直接借助redis本身的expire方式来实现超时设置,主要实现逻辑相差无几

public class DistributeExpireLock {

private static final Integer OUT_TIME = 3;

public static String tryLock(Jedis jedis, String key) {

String value = UUID.randomUUID().toString();

while(true) {

Long ans = jedis.setnx(key, value);

if (ans != null && ans == 1) { // 获取锁成功

jedis.expire(key, OUT_TIME); // 主动设置超时时间为3s

return value;

}

// 获取失败,先确认下是否有设置国超是时间

// 防止锁的超时时间设置失效,导致一直竞争不到

if(jedis.ttl(key) < 0) {

jedis.expire(key, OUT_TIME);

}

}

}

public static void tryUnLock(Jedis jedis, String key, String uuid) {

String ov = jedis.get(key);

if (uuid.equals(ov)) { // 只释放自己的锁

jedis.del(key);

System.out.println(Thread.currentThread() +" del lock success!");

} else {

System.out.println(Thread.currentThread() +" del lock fail!");

}

}

}

获取锁的逻辑相比之前的,就简单很多了,接下来则需要简单的分析下,上面这种实现方式,会不会有坑呢?我们主要看一下获取锁失败的场景

如果获取锁失败

表示有其他的业务方已经获取到了锁

此时,只能等持有锁的业务方主动释放锁

判断锁是否设置了超时时间,若没有则加一个(防止设置超时时间失败导致问题)

从上面这个逻辑来看问题不大,但是有个问题,case :

如某个业务方setnx获取到了锁,但是因为网络问题,过了很久才获取到返回,此时锁已经失效并被其他业务方获取到了,就会出现多个业务方同时持有锁的场景

III. 小结说明

想基于redis实现一个相对靠谱的分布式锁,需要考虑的东西还是比较多的,而且这种锁并不太适用于业务要求特别严格的地方,如

一个线程持有锁时,如果发生gc,导致锁超时失效,但是自己又不知道,此时就会出现多个业务方同时持有锁的场景

对于锁超时的场景,需要仔细考虑,是否会出现并发问题

确保只能释放自己的锁(以防止释放了别人的锁,出现问题)

参考链接

​​基于Redis的分布式锁到底安全吗?​​

​​利用redis实现的分布式锁​​

Redis 实现分布式锁:原理、实现与注意事项(Redisson 之外的轻量级方案) 本文介绍了基于Redis实现分布式锁的轻量级方案,重点讲解了分布式锁的核心要求(互斥性、防死锁、解锁安全等)和Redis实现优势。通过分析三种实现方案的演进过程,指出SETNX+EXPIRE组合的缺陷,推荐使用Redis 2.6.12+的SET NX EX原子指令。文章提供了完整的生产级Java实现代码,包含带详细注释的加锁和解锁逻辑,其中解锁采用Lua脚本确保原子性和安全性。该方案相比Redisson更轻量透明,适合中小型项目使用,并可作为理解分布式锁底层原理的实践案例。 阅读详情

相关推荐

Redis分布式锁的实现及注意事项

分布式锁的释放是一个关键问题。一种常见的做法是为锁设置一个唯一的标识,并在释放锁的时候检查该标识,确保只有持有锁的客户端才能释放锁。Redis的分布式锁默认是不支持重入的,即同一个线程在持有锁的情况下再次请求获取锁会失败。在分布式系统中,为了保证锁的唯一性,需要为每个锁分配一个唯一的标识。通过合理设置锁的过期时间、使用唯一的锁标识、处理锁的重入问题以及确保锁的正确释放,可以提高分布式锁的可靠性和性能。在上述代码中,acquire_lock函数尝试使用SETNX命令获取锁,如果获取成功,则设置锁的过期时间。

DpJulia的博客 213

Redis实现分布式锁相关注意事项

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34007906的博客 295

墨水屏高效开发:架构、开源库与实战优化指南

嵌入式显示技术中,电子墨水屏以其类纸观感和超低功耗特性,在电子书阅读器、智能办公本及工业仪表等场景中占据独特地位。其工作原理基于微胶囊电泳技术,仅在画面刷新时消耗电能,静态显示时功耗近乎为零,这带来了极致的续航优势。为实现流畅的交互体验,开发者需构建分层渲染架构,通过硬件抽象层统一驱动接口,并引入帧缓冲与差异比较算法智能决策局部刷新区域,从而大幅降低刷新延迟与功耗。开源库如GxEPD2和LVGL为墨水屏适配提供了关键支持,结合波形文件管理与电源优化策略,能有效解决残影与卡顿问题。本文聚焦于eink墨水屏高效

weixin_42545636的博客 411

Redis分布式锁原理(一)——redis分布式锁需要注意的问题

1、什么场景会用到分布式锁(用本地锁举例,分布式场景在并发情况下存在的问题) 2、redis为什么可以实现分布式锁 3、假设一分布式场景,运用redis分布式锁并剖析各种坑 结合视频157、158

齐天小圣^O^ 的博客 2923

linux和mac安装+配置circos(

一定要下载完这两个包,GD才会work,要不然会报错,且-modules显示也是fail。官网的教程说的很明白,但是很多包都已经过时了需要在网上找。一般来讲,所有包的安装都不会太困难,除了GD。1.是因为官网给的链接下出来的tgz无法解压。2.我的电脑安装后GD照样是fail的。,进入这个地址下一个.tgz。第二点的原因在于,官网的情况。,进入这个地址,按部就班。GD安装困难有以下几点。搞了一天终于配置成功。

xiufan1的博客 553

从零配置到批量处理:FaceFusion 3.1完整使用指南(含hififace_256模型测试)

本文详细介绍了FaceFusion 3.1的完整使用指南,包括环境配置、模型选择(特别是hififace_256模型的深度测试)以及批量处理技巧。通过AI驱动的脸部替换技术,帮助用户高效实现高质量的面部处理,适用于影视制作、广告设计等多种场景。

weixin_29056865的博客 655

Redis分布式锁注意事项

基于 Redis 的分布式锁的安全性分析 1.1 预防死锁 我们看下面这个典型死锁场景。 一个客户端获取锁成功,但是在释放锁之前崩溃了,此时该客户端实际上已经失去了对公共资源的操作权,但却没有办法请求解锁(删除 Key-Value键值对),那么,它就会一直持有这个锁,而其它客户端永远无法获得锁。 我们的解决方案是:在加锁时为锁设置过期时间,当过期时间到达,Redis 会自动删除对应的 Key-...

努力奔跑 2万+

Vivado实战:UltraScale/UltraScale+器件eFUSE寄存器配置与安全编程全解析

本文详细解析了Xilinx UltraScale/UltraScale+器件中eFUSE寄存器的配置与安全编程方法。从芯片唯一身份标识到加密密钥烧录,再到用户寄存器的灵活应用和安全控制寄存器的配置技巧,全面介绍了如何利用eFUSE功能提升硬件安全性。文章还提供了JTAG接口安全管理和NKZ文件备份方案,帮助开发者避免常见陷阱,确保安全编程的可靠性。

weixin_42535703的博客 431

利用Redisson实现分布式锁,以及分布式锁的常用注意事项

废话少说,直接上代码。

Y_ANXI的博客 299

092、多sensor帧同步在环视系统中的实现——基于瑞芯微RK3588的PPS同步与曝光同步方案

摘要: 本文探讨了瑞芯微RK3588平台在360环视系统中实现多摄像头帧同步的技术方案。针对环视拼接常见的动态场景错位问题,提出了PPS同步与曝光同步相结合的解决方案。通过GPIO硬件触发实现四路摄像头同步曝光,配合I2C全局曝光控制,将时间误差控制在0.5ms内。文章详细解析了RK3588设备树配置、内核驱动实现中的关键细节,包括同步信号处理、寄存器原子写入等核心技术点,并分享了量产中遇到的温度漂移、信号完整性等实际问题及解决方法。最终通过硬件整形和电源优化,将同步抖动控制在±5μs以内,有效解决了动态拼

zzfmlxs的博客 34

微信小程序 - 解决微信支付报错 requestPayment:fail no permission 原因分析及排查处理(支付失败出错,无法唤起支付弹框面板,微信支付API报错请求付款:失败无权限)

微信小程序,微信支付,支付报错,errMsg: "requestPayment:fail no permission",支付失败,支付权限没问题,微信小程序支付报错,检查了appid正确依旧不行,微信小程序支付异常,苹果ios手机,安卓手机,开发者工具模拟器,最新解决教程,小程序wx.requestPayment报错/无响应,小程序支付 requestPaym,微信小程序认证,真机运行,小程序微信支付提示错误,微信小程序里使用微信支付错误提示,微信小程序支付异常,微信支付弹框拉不起来,小程序支付api,都检

🏆 前端领域优质创作者 1万+

使用Redis实现分布式锁及其注意事项

Redis通过SET NX EX和Lua脚本实现分布式锁,注意过期时间、误释放、高可用和性能优化。库存扣减系统实现P99延迟8ms、QPS 12万。锁实现SET NX EX,Lua释放。优化:分片锁、异步。高可用:哨兵、集群。监控Redis分布式锁是高并发系统的核心,未来将在云原生和AI下演进。字数:约5100字(含代码)。如需调整,请告知!Redis通过SET NX EX和Lua脚本实现分布式锁,注意过期、误释放、高可用。库存系统实现P99延迟8ms、QPS 12万。锁SET NX EX。优化。

lssffy的博客 1382

MC_SetOverride指令详细应用介绍(基恩士PLC)

基恩士KV系列PLC和松下总线绝对值伺服运动控制(详细配置+轴控完整ST源代码)

RXXW_Dor的博客 336

redis缓存实现分布式锁原理及注意事项(附代码)

示例代码(Python): 示例代码(JAVA):

zznn0306的博客 947

PCL点云库入门(第1讲)——PCL库简介和安装(Win10/11+VS2019+PCL 1.12.0)

PCL,全称为,即点云库,是一个专注于2D/3D图像和点云处理的大型开源项目。该项目最初由斯坦福大学的杰出计算机视觉专家Radu博士及其团队开发和维护,经过十余年的发展,目前(2024年12月)已更新至1.14.1版本。PCL点云库集成了众多尖端的点云处理算法,这些算法不仅包括基础的滤波、特征估计、表面重建、配准、模型拟合和分割等,还涵盖了更高级的功能,如点云数据的语义理解、场景解析以及动态环境下的实时处理。这些算法能够对含有噪声的点云数据进行有效过滤,去除异常值;

qq_36812406的博客 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

redis实现分布式锁注意事项

解决方案2:设置过期时间和抢占锁这两步需要是原子操作,不能一个成功一个失败,只能同时成功或同时失败, redis支持使用setnx ex命令 ---> set k111 v111 EX 300 NX -- EX 300表示过期时间300秒,NX表示不存在数据才会插入,可以使用ttl k111查看锁的时间。问题4:删除锁时,如果判断是当前用户的锁,下一步正要删除锁的时候,删除之前之前锁已经过期,别人已经设置到了新的值。Redis锁的时间,可以设置长一点,避免锁过期了业务还没执行完,也可以给锁续期。

wyj180的博客 304

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Java的分布式锁的Redis实现与注意事项

本文探讨了Java分布式锁的Redis实现方法及其注意事项。Redis分布式锁通过SETNX等原子操作实现多节点环境下共享资源的独占访问控制。使用过程中需注意:合理配置Redis服务器、避免过度使用锁、处理并发问题、实施系统监控和维护,并确保安全性。正确运用该技术可有效提升分布式系统的稳定性和性能。

2501_90410679的博客 50

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Redis(三)springboot、分布式锁实现与注意事项

Redis 分布式锁需结合原子操作、唯一标识、锁续期及集群容错设计,优先选择成熟库(如 Redisson)以规避复杂边界问题。RedLock 算法:在多个独立 Redis 实例中获取锁,半数以上成功视为有效,需权衡实现复杂度与安 全性。同一客户端多次获取锁时,需维护计数器(如 Redisson 的 hincrby),释放时递减至零。使用成熟库:如 Redisson,内置看门狗、可重入锁、联锁等,减少自实现风险。后台线程定期(如每 10 秒)续期锁,避免业务未完成锁已过期。

mall_0905的博客 342

基于 Redis 实现分布式锁:原理及注意事项

总结基于 Redis 实现分布式锁的原理及注意事项。

YGGP的博客 1005

【分布式id和分布式锁】分布式id实现方案、分布式锁的使用场景、实现方案、注意事项_Redis03

分布式id和分布式锁

Lei锋帽的博客 464

Redis在缓存方面的应用有哪些?如何避免缓存击穿、缓存雪崩等问题?Redis如何实现分布式锁?有哪些注意事项?

锁的过期时间与任务执行时间:如果任务的执行时间超过了锁的过期时间,其他客户端可能会错误地获取到锁并执行相同的任务。因此,需要在获取到锁后,为锁设置一个合适的过期时间,确保它足够长以容纳任务的执行时间。总的来说,Redis实现分布式锁需要综合考虑多个因素,包括锁的过期时间、原子性、死锁问题、锁的粒度以及Redis集群的稳定性等。例如,一些常用的、经常访问的、不经常变化的数据可以存储在Redis中,以减少对数据库的访问。锁的粒度:锁的粒度应该适中,过细的粒度可能导致锁的竞争过于激烈,影响性能;

Aaron的博客 703

Redis实现分布式锁

Redis 分布式锁是解决分布式系统中资源竞争问题的有效方法。通过使用 Redis 的原子性命令和 Lua 脚本,可以实现一个简单而高效的分布式锁。Java 开发者可以使用 Jedis 等 Redis 客户端库方便地实现分布式锁,并在实际应用中结合续租机制和高可用策略来提高锁的可靠性和稳定性。Redis 分布式锁适用于各种需要确保数据一致性和并发控制的场景,如分布式事务、资源访问控制等。

Flying_Fish_roe的博客 1284

go 使用lua脚本实现redis分布式锁

分布式锁的要求 实现分布式锁之前要明确一下分布式锁的要求 互斥性,在任意时刻,只能有一个进程持有锁 防死锁,不能因为持有锁的客户端宕机而使其他进程无法获取到锁。 加锁和解锁的必须是同一个进程。 保证锁的续租。 redis分布式锁的优缺点 redis实现的分布式锁性能会比zookeeper、etcd等实现的要好,但因为单点故障或者主备异步复制的问题,可能会出现当master宕机crash会导致多个client同时持有分布式锁。(这里的方案会出现这些问题) 因为etcd的高可靠、强一致存储,可以

weixin_46040684的博客 1260

【redis】Redis 分布式锁

针对上一篇redis的简单应用,这里做下延申redis分布式锁。

a408492801的博客 414

如何使用 Redis 实现分布式锁?

Redis 是一个高性能的内存数据库,支持多种数据结构(字符串、哈希、列表等),具有持久化、高并发和集群支持等特点。它广泛应用于缓存、会话存储、消息队列等场景,还能通过原子操作实现分布式锁。本文介绍了 Redis 的核心功能、数据结构操作示例(包括 Python 实现),以及利用 SET 命令和 Lua 脚本实现分布式锁的具体方案,确保互斥性和安全性。

前端技术的学习整理 1185
上一篇: 浅析微服务架构应该在什么时候采用
下一篇: 8000字让你知道NoSQL是什么
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值