1、設置分布式鎖
/** * 設置redis 分布式鎖 * @param lockName * @param acquireTimeout * @param lockTimeout * @return */ public String acquireDistributedLockWithTimeout(String lockName, long acquireTimeout, int lockTimeout) { String lockValue = UUID.randomUUID().toString(); String lockKey = "lock:" + lockName; long acquireTime = System.currentTimeMillis() + acquireTimeout; ValueOperations ops = this.redisTemplate.opsForValue(); while(acquireTime > System.currentTimeMillis()) { boolean locked = ops.setIfAbsent(lockKey, lockValue); if (locked) { this.redisTemplate.expire(lockKey, (long)lockTimeout, TimeUnit.SECONDS); return lockValue; } try { TimeUnit.MILLISECONDS.sleep(1L); } catch (InterruptedException var12) { Thread.currentThread().interrupt(); } } return null; }
2、釋放redis分布式鎖
/** * 釋放redis鎖 * @param lockName * @param lockValue * @return */ public boolean releaseDistributedLock(String lockName, String lockValue) { String lockKey = "lock:" + lockName; List<Object> result = null; ValueOperations ops = this.redisTemplate.opsForValue(); do { this.redisTemplate.watch(lockKey); if (!Objects.equal(lockValue, ops.get(lockKey))) { break; } this.redisTemplate.delete(lockKey); } while(result == null); this.redisTemplate.unwatch(); return true; }
3、定時邏輯
//集群環境 定時任務加鎖,保證執行一次 異常情況6個小時 釋放鎖 String lock = redisService.acquireDistributedLockWithTimeout("incomeStatistics", 10, 60*60*6); //判斷是否獲得鎖 if(StringUtils.isNotBlank(lock)){ logger.info("定時任務 開始執行"); try{ //業務邏輯 }catch (Exception e){ //異常處理 } finally { //釋放鎖 redisService.releaseDistributedLock("incomeStatistics",lock); } }