diff --git a/mallinkService/src/main/java/com/iformall/utils/RedisLock.java b/mallinkService/src/main/java/com/iformall/utils/RedisLock.java index d9bdeb9d2..e8e8b99af 100644 --- a/mallinkService/src/main/java/com/iformall/utils/RedisLock.java +++ b/mallinkService/src/main/java/com/iformall/utils/RedisLock.java @@ -4,9 +4,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; +import java.util.concurrent.TimeUnit; + /** * RedisLock * User: Stormeye @@ -29,17 +32,19 @@ public class RedisLock { * @return */ public boolean lock(String key,String value){ - if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){//对应setnx命令 + ValueOperations operations = stringRedisTemplate.opsForValue(); + if(operations.setIfAbsent(key,value)){//对应setnx命令 + operations.set(key, value, 1, TimeUnit.SECONDS); //可以成功设置,也就是key不存在 return true; } //判断锁超时 - 防止原来的操作异常,没有运行解锁操作 防止死锁 - String currentValue = stringRedisTemplate.opsForValue().get(key); + String currentValue = operations.get(key); //如果锁过期 if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){//currentValue不为空且小于当前时间 //获取上一个锁的时间value - String oldValue =stringRedisTemplate.opsForValue().getAndSet(key,value);//对应getset,如果key存在 + String oldValue =operations.getAndSet(key,value);//对应getset,如果key存在 //假设两个线程同时进来,key被占用了。获取的值currentValue=A(get取的旧的值肯定是一样的),两个线程的value都是B,key都是K.锁时间已经过期了。 //而这里面的getAndSet一次只会一个执行,也就是一个执行之后,上一个的value已经变成了B。只有一个线程获取的上一个值会是A,另一个线程拿到的值是B。