redistemplate实现 setnx分布式锁
2020-04-07 01:37
204 查看
使用RedisTemplate的execute的回调方法,里面使用Setnx方法
Setnx就是,如果没有这个key,那么就set一个key-value, 但是如果这个key已经存在,那么将不会再次设置,get出来的value还是最开始set进去的那个value.
接下来我们用代码的形式展现:
@Component public class CommonRedisHelper { //锁名称 public static final String LOCK_PREFIX = "redis_lock"; //加锁失效时间,毫秒 public static final int LOCK_EXPIRE = 300; // ms @Autowired RedisTemplate redisTemplate; /** * 最终加强分布式锁 * * @param key key值 * @return 是否获取到 */ public boolean lock(String key){ String lock = LOCK_PREFIX + key; // 利用lambda表达式 return (Boolean) redisTemplate.execute((RedisCallback) connection -> { long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1; Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes()); if (acquire) { return true; } else { byte[] value = connection.get(lock.getBytes()); if (Objects.nonNull(value) && value.length > 0) { long expireTime = Long.parseLong(new String(value)); // 如果锁已经过期 if (expireTime < System.currentTimeMillis()) { // 重新加锁,防止死锁 byte[] oldValue = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes()); return Long.parseLong(new String(oldValue)) < System.currentTimeMillis(); } } } return false; }); } /** * 删除锁 * * @param key */ public void delete(String key) { redisTemplate.delete(key); } }
如何使用呢,导入工具类后:
CommonRedisHelper redisHelper = new CommonRedisHelper(); ?1boolean lock = redisHelper.lock(key); if (lock) { // 执行逻辑操作 redisHelper.delete(key); } else { // 设置失败次数计数器, 当到达5次时, 返回失败 int failCount = 1; while(failCount <= 5){ // 等待100ms重试 try { Thread.sleep(100l); } catch (InterruptedException e) { e.printStackTrace(); } if (redisHelper.lock(key)){ // 执行逻辑操作 redisHelper.delete(key); }else{ failCount ++; } } throw new RuntimeException("现在创建的人太多了, 请稍等再试"); }
相关文章推荐
- Spring boot2.X 简单尝试 RedisTemplate 实现分布式锁
- spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑
- SpringBoot项目:RedisTemplate实现轻量级消息队列
- SpringBoot 2.x整合Redis实现RedisTemplate以及缓存
- RedisTemplate实现分布式锁
- RedisTemplate实现分布式锁
- redission计数器实现,redisTemplate计数器
- SpringBoot2.X 整合RedisTemplate 简单实现消息队列
- 扩展redisTemplate实现分布式锁
- RedisTemplate实现事物问题剖析和解决
- Spring Data Redis 二:RedisTemplate实现事物问题剖析和解决
- Redis-RedisTemplate 缓存操作具体实现代码
- SpringBoot集成Redis的实现示例
- redis实现分布式锁
- redis集群环境搭建以及java中jedis客户端集群代码实现
- redis实现session共享
- mysql,redis客户端连接池和线程池的Linux C编程实现(★firecat推荐★)
- spring boot + redis 实现session共享
- 为什么Java不使用redis的数据结构来设计HashMap的底层实现?
- 利用redis的订阅和发布来实现实时监控的一个DEMO(Python版本)