背景项目组已经有个分布式锁注解(参考前文《记一次分布式锁注解化》),但是在设置锁过期时间时,需要去预估业务耗时时间,如果锁的过期时间能根据业务运行时间自动调整,那使用的就更方便了。
思路
思路参考了redisson:保留原先的可自定义设置过期时间,只有在没有设置过期时间(过期时间为默认值0)的情况下,才会启动自动延长。
申请锁时,设置一个延长过期时间,定时每隔延长过期时间的三分之一时间就重新设置过期时间(时期时间值为延长过期时间)。
为了防止某次业务由于异常而出现任务持续很久,从而长时间占有了锁,添加最大延期次数参数。
加锁用一个Map来存储需要续期的任务信息。
在加锁成功之后将任务信息放入Map,并启动延迟任务,延迟任务在执行延期动作前先检查下Map里锁数据是不是还是被当前任务持有。
每次续期任务完成并且成功之后,就再次启动延迟任务。
申请锁
复用之前的加锁方法,把延长过期时间作为加锁过期时间。public Lock acquireAndRenew(String lockKey, String lockValue, int lockWatchdogTimeout) {
return acquireAndRenew(lockKey, lockValue, lockWatchdogTimeout, 0);
}
public Lock acquireAndRenew(String lockKey, String lockValue, int lockWatchdogTimeout, int maxRenewTimes) {
if (lockKey == null || lockValue == null || lockWatchdogTimeout <= 0) {
return new Lock(this).setSuccess(false).setMessage("illegal argument!");
}
Lock lock = acquire(lockKey, lockValue, lockWatchdogTimeout);
if (!lock.isSuccess()) {
return lock;
}
expirationRenewalMap.put(lockKey, new RenewLockInfo(lock));
scheduleExpirationRenewal(lockKey, lockValue, lockWatchdogTimeout, maxRenewTimes, new AtomicInteger());
return lock;
}
定时续期
当前锁还未被释放(Ma