redis实现锁机制

本文探讨了使用Redis实现分布式锁的两种方法:INCR和SETNX,强调了独占性和避免死锁的重要性。通过设置过期时间确保锁自动释放,以防止死锁。同时,提出了在锁过期后,客户端可能未完成执行的风险,并给出了解决方案,即在删除锁前验证客户端ID。
摘要由CSDN通过智能技术生成

实现锁的关键点:1.独占性;2.避免死锁

思路很多,举几个例子:

1.INCR

思路:如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作进行加一。然后其它用户在执行 INCR 操作进行加一时,如果返回的数大于 1 ,说明这个锁正在被使用当中。

独占性:返回值为1才算获得了锁,因为redis的命令具有原子性,即使多个客户端同时执行,只会有一个客户端的返回值为1。

避免死锁:expire设置过期时间,过期后锁失效。

1、 客户端A请求服务器获取key的值为1表示获取了锁
2、 客户端B也去请求服务器获取key的值为2表示获取锁失败
3、 客户端A执行代码完成,删除锁
4、 客户端B在等待一段时间后在去请求的时候获取key的值为1表示获取锁成功
5、 客户端B执行代码完成,删除锁

incr lockid;
expire lockid 5;  //设置5秒后过期

2.SETNX

思路:如果 key 不存在,将 key 设置为 value。如果 key 已存在,则 SETNX 不做任何动作。

独占性:如果key已存在,其他客户端通过setnx无法获取锁。

避免死锁:expire设置过期时间,过期后锁失效。

1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功
2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败
3、 客户端A执行代码完成,删除锁
4、 客户端B在等待一段时间后在去请求设置key的值,设置成功
5、 客户端B执行代码完成,删除锁

setnx lockid pid;
expire lockid 5;  //设置5秒后过期

新问题:借助 expire 来设置过期时间,获取锁就不是原子性操作了。如果代码执行出现意外,只创建了锁,没有执行expire,锁将会一直存在。

解决思路:SET 命令本身已经从版本 2.6.12 开始包含了设置过期时间的功能,redis的命令具有原子性。

3.SET

思路:类似SETNX,SET还可以设置过期时间。SET key value [EX seconds|PX milliseconds] [NX|XX]。

独占性:[NX|XX]中NX参数表示key不存在时,才能创建key。

避免死锁:[EX seconds|PX milliseconds]中,设置过期时间的单位是秒还是毫秒。

1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功
2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败
3、 客户端A执行代码完成,删除锁
4、 客户端B在等待一段时间后在去请求设置key的值,设置成功
5、 客户端B执行代码完成,删除锁

set lockid pid ex 5 nx;

新问题:如果锁过期后,客户端A还没执行完,然后客户端B获取到了锁,这时候客户端A执行完了,会不会在删锁的时候把B的锁给删掉?

解决思路:key命名为锁id,value设置为客户端id,客户端要删除锁之前,先获取锁的value,对比自己的客户端id,再判断要不要删除。

这一部分大家在业务代码里面自行实现。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值