StringRedisTemplate实现 redis分布式锁 学习

StringRedisTemplate实现 redis分布式锁 学习

public interface RedisLock {

    public boolean lock(String id);

    public boolean unlock(String id);

}

实现类:

package com.cmcc.open.ss.service.impl;

import com.cmcc.open.ss.service.RedisLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Collections;

/**
 * @author hm
 * @Description: TODO
 * @date 2021/5/12
 * @Version 1.0
 */
@Service
public class RedisLockImpl implements RedisLock {


    private static final Long EXEC_RESULT = 1l;
    private static final String REDIS_LOCK_KEY = "redis_lock_key";
    private static final String REDIS_LOCK_KEY_EXPIRE_TIME = "30";//30s
    @Autowired
    private StringRedisTemplate redisTemplate;


    private static final String LUA_LOCK =
        "if redis.call('setNx',KEYS[1],ARGV[1]) then
" +
            "    if redis.call('get',KEYS[1])==ARGV[1] then
" +
            "        return redis.call('expire',KEYS[1],ARGV[2])
" +
            "    else
" +
            "        return 0
" +
            "    end
" +
            "end
";

    private static final String LUA_UN_LOCK =
        "if redis.call('get',KEYS[1]) == ARGV[1] then
" +
            "    return redis.call('del',KEYS[1])
" +
            "else
" +
            "    return 0
" +
            "end";

    @Override
    public boolean lock(String id) {
        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(LUA_LOCK);
        redisScript.setResultType(String.class);
        Object result = redisTemplate.execute(redisScript, Collections.singletonList(REDIS_LOCK_KEY), id, REDIS_LOCK_KEY_EXPIRE_TIME);
        if ("1".equals(result.toString())) {
            return true;
        }
        return false;
    }

    @Override
    public boolean unlock(String id) {
        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(LUA_UN_LOCK);
        redisScript.setResultType(String.class);
        Object result = redisTemplate.execute(redisScript, Collections.singletonList(REDIS_LOCK_KEY), id);
        if ("1".equals(result.toString())) {
            return true;
        }
        return false;
    }


}

controller测试:

package com.cmcc.open.acs.controller;

import com.cmcc.open.acs.service.PortalApiAusService;
import com.cmcc.open.ss.service.RedisLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.UUID;

/**
 * @author hm
 * @Description: TODO
 * @date 2021/4/27
 * @Version 1.0
 */
@Controller
@RequestMapping("/{version}")
public class Test {

    private static Logger log = LoggerFactory.getLogger(Test.class);

    private static int count=0;
    @Autowired
    RedisLock redisLock;

    /**存储随机数**/
    private static final ThreadLocal<String> local = new ThreadLocal<>();

    @RequestMapping(value = "/hello")
//    @Authentication
    @ResponseBody
    public String queryNumSensitivity() {
        String uuid= UUID.randomUUID().toString().replaceAll("-", "");
        try {
            log.info("uuid={}", uuid);
            if (redisLock.lock(uuid)) {
                log.info("get lock succ");
                //获取锁成功
                local.set(uuid);
                count++;
                log.info("count={}",count);
                log.info("sleep start.....");
                Thread.sleep(10000l);
                log.info("sleep end");

                redisLock.unlock(uuid);
                local.remove();
                return count+"";
            }else{
                log.info("get lock fail");
                return "get lock fail";
                //没拿到锁
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "hello";
    }

}
原文地址:https://www.cnblogs.com/wuyun-blog/p/14767928.html