0

0

redis加锁的方式有哪些

WBOY

WBOY

发布时间:2023-05-27 12:43:06

|

2454人浏览过

|

来源于亿速云

转载

redis常见的加锁命令分别是incr、setnx、set

1、INCR

这种锁的加锁思路是:

key不存在,那么key的值会先被初始化为0,然后再执行INCR操作进行加一。

然后其它用户在执行INCR操作进行加一时,如果返回的数值大于1,说明这个key正在被锁定使用。

1、 客户端A请求服务器获取key的值为1表示获取了锁    

2、 客户端B也去请求服务器获取key的值为2表示获取锁失败    

3、 客户端A执行代码完成,删除锁    

4、 客户端B在等待一段时间后在去请求的时候获取key的值为1表示获取锁成功    

5、 客户端B执行代码完成,删除锁 

$redis->incr($key);
$redis->expire($key, $ttl); //设置生成时间为1秒

具体使用命令:

127.0.0.1:6379>INCR keyName

2、SETNX

这种加锁的思路是,如果key不存在,将key设置为value,如果key存在,则SETNX不做任何动作。

SETNX是SET if Not eXists的缩写。

1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

3、 客户端A执行代码完成,删除锁

4、 客户端B在等待一段时间后在去请求设置key的值,设置成功

5、 客户端B执行代码完成,删除锁

$redis->setNX($key, $value);
$redis->expire($key, $ttl);

具体使用命令:

redis> SETNX keyName value
(integer) 1

设置成功,返回1;设置失败,返回0

3、SET

上面两种方法都有一个问题,会发现,都需要设置 key 过期。

那么为什么要设置key过期呢?

如果请求执行因为某些原因意外退出了,导致创建了锁但是没有删除锁,那么这个锁将一直存在,以至于以后缓存再也得不到更新。

HMCSS通用企业网站系统1.0
HMCSS通用企业网站系统1.0

HMCSS是由河马工作室全新开发的通用的企业网站系统,是PHP+MYSQL的架构,采用DIV+CSS的方式进行网页布局,网站的功能包括有:企业简介,图片展示幻灯,产品图片滚动,企业荣誉,实力展示,产品分类及展示,网上招聘,在线留言,联系我们,在线地图等内容,另外还带有完整的管理后台,如网站SEO优化关键词等都可以自由设定。 HMCSS目前发布的是1.0版本,就是上述的这些内容。后面我们还要加上产品

下载

于是乎我们需要给锁加一个过期时间以防不测。

但是借助 Expire 来设置就不是原子性操作了。

所以还可以通过事务来确保原子性,但是还是有些问题,所以官方就引用了另外一个,使用 SET 命令本身已经从版本 2.6.12 开始包含了设置过期时间的功能。

1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败    

3、 客户端A执行代码完成,删除锁    

4、 客户端B在等待一段时间后在去请求设置key的值,设置成功

5、 客户端B执行代码完成,删除锁

$redis->set($key, $value, array('nx', 'ex' => $ttl));  //ex表示秒

具体使用:

redis>set key value NX EX max-lock-time 实现加锁

命令解释:

  • key:key就是redis的key值作为锁的标识,value在这里作为客户端的标识,只有key-value都比配才有删除锁的权利【保证安全性】

  • max-lock-time:通过max-lock-time设置过期时间保证不会出现死锁【避免死锁】

  • NX:只有这个key不存才的时候才会进行操作,if not exists;

  • EX:设置key的过期时间为秒,具体时间由第5个参数决定

加锁代码: 

 Jedis jedis = new Jedis("127.0.0.1", 6379);
 private static final String SUCCESS = "OK";
 /**
  * 加锁操作
  * @param key 锁标识
  * @param value 客户端标识
  * @param timeOut 过期时间
  */
  
 public Boolean lock(String key,String value,Long timeOut){
     String var1 = jedis.set(key,value,"NX","EX",timeOut);
     if(LOCK_SUCCESS.equals(var1)){
         return true;
     }
     return false;
 }

解锁代码:

 Jedis jedis = new Jedis("127.0.0.1", 6379); 
 private static final Long UNLOCK_SUCCESS = 1L;
 /**
  * 解锁操作
  * @param key 锁标识
  * @param value 客户端标识
  * @return
  */
  
 public static Boolean unLock(String key,String value){
     String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return 
     redis.call(\"del\",KEYS[1]) else  return 0 end";
     Object var2 = jedis.eval(luaScript,Collections.singletonList(key), Collections.singletonList(value));
     if (UNLOCK_SUCCESS == var2) {
         return true;
     }
     return false;
}

luaScript 这个字符串是个lua脚本,代表的意思是如果根据key拿到的value跟传入的value相同就执行del,否则就返回0【保证安全性】

jedis.eval(String,list,list);这个命令就是去执行lua脚本,KEYS的集合就是第二个参数,ARGV的集合就是第三参数【保证解锁的原子操作】

上述就实现了怎么使用redis去正确的实现分布式锁,但是有个小缺陷就是锁过期时间要设置为多少合适,这个其实还是需要去根据业务场景考量一下的。

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

321

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

231

2023.10.07

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

314

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

719

2023.08.22

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1458

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

612

2023.11.24

PPT动态图表制作教程大全
PPT动态图表制作教程大全

本专题整合了PPT动态图表制作相关教程,阅读专题下面的文章了解更多详细内容。

13

2026.01.07

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号