Redis——》死锁

推荐链接:
    总结——》【Java】
    总结——》【Mysql】
    总结——》【Redis】
    总结——》【Kafka】
    总结——》【Spring】
    总结——》【SpringBoot】
    总结——》【MyBatis、MyBatis-Plus】
    总结——》【Linux】
    总结——》【MongoDB】
    总结——》【Elasticsearch】

Redis——》死锁

  • 一、死锁场景
  • 二、如何避免死锁
    • 1、两条命令实现:SETNX加锁 + EXPIRE过期时间
      • (1)实现
      • (2)优点
      • (3)缺点
    • 2、一条命令实现:SET加锁 + EXPIRE过期时间
      • (1)实现
      • (2)优点
      • (3)缺点

一、死锁场景

// 加锁
SETNX lock_key 1

// 业务逻辑
DO THINGS

// 释放锁,删除key
DEL lock_key

以下情况会导致已经获得锁的客户端一直占用锁,其他客户端永远无法获取到锁,这就是死锁:

  1. 程序处理业务逻辑异常,没及时释放锁
  2. 进程挂了,没机会释放锁

二、如何避免死锁

方案:给锁设置一个过期时间
示例:假设操作共享资源的时间不会超过10s,那么加锁时,给这个key设置10s过期。

1、两条命令实现:SETNX加锁 + EXPIRE过期时间

(1)实现

SETNX lock_key 1    // 加锁
EXPIRE lock_key 10  // 10s后自动过期

(2)优点

锁可以被自动释放,其它客户端依旧可以拿到锁

(3)缺点

如果过期时间设置失败,依旧发生死锁问题。

原因:
加锁、设置过期时间是2条命令,这2条命令不能保证是原子操作(一起成功),有可能只执行了第一条,第二条却执行失败

场景:

  1. SETNX执行成功,执行EXPIRE时由于网络问题,执行失败
  2. SETNX执行成功,Redis异常宕机,EXPIRE没有机会执行
  3. SETNX执行成功,客户端异常崩溃,EXPIRE没有机会执行

2、一条命令实现:SET加锁 + EXPIRE过期时间

在Redis 2.6.12之后,Redis扩展了SET命令的参数,可以在SET的同时指定EXPIRE时间,这条操作是原子的。

(1)实现

SET lock_key 1 EX 10 NX // 10s后自动过期

(2)优点

解决死锁问题

(3)缺点

可能发生释放别人的锁(参考链接:Redis——》锁被别人释放)

你可能感兴趣的:(redis,死锁,过期,setnx,expire)