Redis分布式锁的示例分析
短信预约 -IT技能 免费直播动态提醒
小编给大家分享一下Redis分布式锁的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
第一版本:
@Override
public <T> Long set(String key,T value, Long cacheSeconds) {
if (value instanceof HashMap) {
BoundHashOperations valueOperations = redisTemplate.boundHashOps(key);
valueOperations.putAll((Map) value);
valueOperations.expire(cacheSeconds, TimeUnit.SECONDS);
}
else{
//使用map存储
BoundHashOperations valueOperations = redisTemplate.boundHashOps(key);
valueOperations.put(key, value);
//秒
valueOperations.expire(cacheSeconds, TimeUnit.SECONDS);
}
return null;
}
@Override
public void del(String key) {
redisTemplate.delete(key);
}
采用set 和 del 完成锁的占用与释放,后经测试得知,set不是线程安全,在并发情况下常常会导致数据不一致.
第二版本:
public boolean getLock(int range, String key) {
ValueOperations<String, Integer> valueOper1 = template.opsForValue();
return valueOper1.increment(key, 1) <= range;
}
public void initLock(String key, Long expireSeconds) {
ValueOperations<String, Integer> operations = template.opsForValue();
template.setKeySerializer(new GenericJackson2JsonRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
operations.set(key, 0, expireSeconds * 1000);
}
public void releaseLock(String key) {
ValueOperations<String, Integer> operations = template.opsForValue();
template.setKeySerializer(new GenericJackson2JsonRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.delete(key);
}
采用redis的 increament操作完成锁的抢占.但是释放锁时,是每个线程都可以删除redis中的key值. 并且initLock会降上一次的操作给覆盖掉,所以也废弃掉此方法
最终版本:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;
import redis.clients.jedis.Jedis;
import java.lang.reflect.Field;
import java.util.Collections;
@Service
public class RedisLock {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
@Autowired
private RedisConnectionFactory connectionFactory;
public boolean lock(String lockKey, String requestId, int expireTime) {
Field jedisField = ReflectionUtils.findField(JedisConnection.class, "jedis");
ReflectionUtils.makeAccessible(jedisField);
Jedis jedis = (Jedis) ReflectionUtils.getField(jedisField, connectionFactory.getConnection());
String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;
}
public boolean releaseLock(String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = getJedis().eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
}
public Jedis getJedis() {
Field jedisField = ReflectionUtils.findField(JedisConnection.class, "jedis");
ReflectionUtils.makeAccessible(jedisField);
Jedis jedis = (Jedis) ReflectionUtils.getField(jedisField, connectionFactory.getConnection());
return jedis;
}
}
以上是“Redis分布式锁的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341