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\n" + " if redis.call('get',KEYS[1])==ARGV[1] then\n" + " return redis.call('expire',KEYS[1],ARGV[2])\n" + " else\n" + " return 0\n" + " end\n" + "end\n"; private static final String LUA_UN_LOCK = "if redis.call('get',KEYS[1]) == ARGV[1] then\n" + " return redis.call('del',KEYS[1])\n" + "else\n" + " return 0\n" + "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"; } }