🎨 redis 分布式锁

This commit is contained in:
fuhouyin 2023-11-24 10:19:43 +08:00
parent 6d6569a314
commit 7c2ac27f63

View File

@ -1,13 +1,17 @@
package utils.redis;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -15,12 +19,16 @@ import java.util.concurrent.TimeUnit;
* @author fuhouyin
* @time 2023/4/11 9:30
*/
@Slf4j
@Component
public class RedisCacheUtils {
@Autowired
private RedisTemplateProvider redisTemplateProvider;
@Autowired
private RedisTemplate redisTemplate;
private final StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
public static final String SETNX_SCRIPT = "return redis.call('setnx',KEYS[1], ARGV[1])";
public void setValue(String key, Object value){
RedisTemplate redisTemplate = getRedisTemplate();
@ -88,10 +96,50 @@ public class RedisCacheUtils {
return result;
}
/**
* 指定缓存失效时间
*/
public void expire(String key, long time) {
redisTemplate.expire(key, time, TimeUnit.MILLISECONDS);
}
/**
* 根据key 获取过期时间
*
* @param key 不能为null
* @return 时间(毫秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.MILLISECONDS);
}
public Boolean lock(String key){
return getRedisTemplate().opsForValue().setIfAbsent(key, BigDecimal.ZERO.intValue());
}
/**
* redis实现分布式锁
* @param key time是毫秒毫秒毫秒毫秒毫秒
* @return
*/
public boolean lock(String key,Long time) {
//自定义脚本
DefaultRedisScript<List> script = new DefaultRedisScript<>(SETNX_SCRIPT, List.class);
//执行脚本,传入参数,由于value没啥用,这里随便写死的"1"
List<Long> rst = (List<Long>) redisTemplate.execute(script, Collections.singletonList(key), "1");
//返回1,表示设置成功,拿到锁
if(rst.get(0) == 1){
log.info(key+"成功拿到锁");
//设置过期时间
expire(key,time);
log.info(key+"已成功设置过期时间:"+time +"");
return true;
}else{
long expire = getExpire(key);
log.info(key+"未拿到到锁,还有"+expire+"释放");
return false;
}
}
public Boolean tryLock(String key){
try {
for (int i = 0; i < 3; i++) {