2024-05-02  阅读(1)
版权声明:本文为博主付费文章,严禁任何形式的转载和摘抄,维权必究。 本文链接:https://www.skjava.com/mianshi/baodian/detail/2114362888

回答

SETNX 是 "SET if Not eXists" 的缩写,它所表达的意思是只有在 key 不存在时才设置值。它能够实现分布式锁的主要原因有两点:

  1. Redis 单线程保证 SETNX 的原子性SETNX 是 Redis 中的一个命令,Redis 中的命令执行都是原子性的,这就保证了 SETNX 在执行过程中是不会被其他命令打断的。当我们使用 SETNX 设置一个 key 时,如果这个 key 已经存在,SETNX 将不会执行任何操作并返回 0;如果这个 key 不存在,它将设置 key的值并返回 1。
  2. 独占性SETNX 的语义是"SET if Not eXists"。这就意味着如果某个客户端成功使用 SETNX 设置了一个 key,那么在这个键过期或被删除之前,其他客户端是不可以再次使用 SETNX 成功设置相同的 key。这就实现了锁的独占性,确保了在分布式系统中,同一时刻只有一个客户端可以获得锁。

SETNX 的优点在于它实现分布式锁的逻辑很简单,容易理解和实现。同时使用 Redis 的基本特性,保证了加锁的正确性,同时性能较好。

但是,SETNX 的缺点则更加明显:

  • 锁无法续期:若获取锁的业务逻辑执行时间比较长,超过了锁的过期时间,则可能会导致锁被提前释放而产生系统风险。
  • 无法可重入:同一个线程无法多次重复获取同一把锁。
  • 可能会产生死锁:在 SETNX 和设置过期时间(如使用 EXPIRE 命令)之间,如果服务器宕机或操作未能成功完成,可能导致锁永久存在,造成死锁。

所以,如果我们想要一个功能比较完善的分布式锁,则可以使用 Redisson 来实现分布式锁:

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