🎨 redis 分布式锁
This commit is contained in:
parent
6d6569a314
commit
7c2ac27f63
@ -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++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user