日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

RedisTemplate實(shí)現(xiàn)setnx分布式鎖

作者:毅大師 更新時(shí)間: 2022-05-25 編程語言

RedisTemplate由于沒有setnx指令,所以需要自定義腳本時(shí)間

?一、請直接復(fù)制

package com.zy.base.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * redis 工具類
 * @Author ZhangYi
 */
@Component
@Slf4j
public class RedisUtil {

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * lua 腳本
     */
    public static final String SETNX_SCRIPT = "return redis.call('setnx',KEYS[1], ARGV[1])";

    /**
     * redis實(shí)現(xiàn)分布式鎖
     * @param key
     * @return
     */
    public boolean setNx(String key,int time) {
        //自定義腳本
        DefaultRedisScript script = new DefaultRedisScript<>(SETNX_SCRIPT, List.class);
        //執(zhí)行腳本,傳入?yún)?shù),由于value沒啥用,這里隨便寫死的"1"
        List rst = redisTemplate.execute(script, Collections.singletonList(key), "1");
        //返回1,表示設(shè)置成功,拿到鎖
        if(rst.get(0) == 1){
            log.info(key+"成功拿到鎖");
            //設(shè)置過期時(shí)間
            expire(key,time);
            log.info(key+"已成功設(shè)置過期時(shí)間:"+time +" 秒");
            return true;
        }else{
            long expire = getExpire(key);
            log.info(key+"未拿到到鎖,還有"+expire+"釋放");
            return false;
        }
    }
    
    /**
     * 指定緩存失效時(shí)間
     *
     * @param key  鍵
     * @param time 時(shí)間(秒)
     * @return
     */
    public void expire(String key, long time) {
        redisTemplate.expire(key, time, TimeUnit.SECONDS);
    }

    /**
     * 根據(jù)key 獲取過期時(shí)間
     *
     * @param key 鍵 不能為null
     * @return 時(shí)間(秒) 返回0代表為永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 刪除緩存
     *
     * @param key 可以傳一個(gè)值 或多個(gè)
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection) CollectionUtils.arrayToList(key));
            }
        }
    }


}

二、使用栗子

redisUtil.setNx("zyLock1",5);

過期時(shí)間是為了防止死鎖,當(dāng)業(yè)務(wù)執(zhí)行完畢,刪除key釋放鎖

原文鏈接:https://zhangyi520.blog.csdn.net/article/details/124926230

欄目分類
最近更新