Redis 分布式鎖 解決集群環境下多次定時任務執行


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);
            }
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM