相信在日常开发中,基于 Redis 天然支持分布式锁,大家在线上分布式项目中都使用过 Redis 锁。本文主要针对某些异常场景下,加锁代码执行时间超过了加锁时间,导致任务还没执行完,但是锁已经释放的问题进行讲解并给出实践代码。
一、过期时间
一般情况下我们加锁时,都会指定过期时间参数,当任务执行时间超过了锁过期时间,下一个任务进来时就会获取到锁,造成异常。
针对过期时间常见有两种处理方法:
- 自动续期:锁快到期时,通过定时任务自动续期
- 加锁不设置过期时间:任务不执行完,锁就不会过期
这里博主给出自己的分析:
第一种方案:当设置了过期时间后,如果还执行自动续期操作,那么这个锁的实际过期时间就与我们在加锁时设置的过期时间不符合,产生了逻辑上的冲突!所以博主认为自动续期操作对已经设置了过期时间的锁不适用。
第二种方案:加锁不设置过期时间的话,理论上好像是可以解决这个问题,任务不执行完,锁就不会释放。但是实际针对一些极端异常场景下,如果任务执行过程中,服务器宕机、网络断连等都可能造成锁释放不了,比如加锁成功了,执行中发生了宕机,程序直接没了,但是锁还在,另一个任务就一直获取不到锁。
综合来看:博主认为如果加锁代码需要添加过期时间,其实不需要进行自动续期操作。当我们需要确保当前任务没执行完,下一个任务一定不能获取到锁时,可以不设置过期时间。
那怎么避免第二种方案中,异常场景下,锁一直未释放的问题嘞?
答案是在加锁成功时,如果没有指定过期时