使用redis incr处理并发,存在死锁问题

@Autowired
private RedisTemplate redisTemplate;

/**
 * 加锁
 */
public boolean getLock(String key) {
	 try {
		 long count = redisTemplate.opsForValue().increment(key, 1);
		 //此段代码出现异常则会出现死锁问题,key一直都存在
		 if(count == 1){
			 //设置有效期2秒
			 redisTemplate.expire(key, 2, TimeUnit.SECONDS);
			 return true;
		 }
		 //如果存在表示重复
		 return false;
	 } catch (Exception e) {
		 logger.error("redis加锁异常", e);
		 redisTemplate.delete(key);		//出现异常删除锁
		 return true;
	 }
}

当正常情况没有问题,但是当计数器设置成功后,服务出现异常,那么这个key会永远存在,这样肯定不行。

Redis Incr 命令将 key 中储存的数字值增一,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作,且将key的有效时间设置为长期有效。

修改后的代码

@Autowired
private RedisTemplate redisTemplate;

/**
 * 加锁
 */
public boolean getLock(String key) {
	 try {
		 long count = redisTemplate.opsForValue().increment(key, 1);
		 if(count == 1){
			 //设置有效期2秒
			 redisTemplate.expire(key, 2, TimeUnit.SECONDS);
			 return true;
		 }else{
			 long time = redisTemplate.getExpire(key,TimeUnit.SECONDS);
			 if(time == -1){
				 //设置失败重新设置过期时间
				 redisTemplate.expire(key, 2, TimeUnit.SECONDS);
				 return true;
			 }
		 }
		 //如果存在表示重复
		 return false;
	 } catch (Exception e) {
		 logger.error("redis加锁异常", e);
		 redisTemplate.delete(key);		//出现异常删除锁
		 return true;
	 }
}

猜你喜欢

转载自blog.csdn.net/u011974797/article/details/81238079